refactor choice parsing

This commit is contained in:
Arpad Ryszka 2017-06-26 00:04:16 +02:00
parent c1c9a03ff4
commit 6a179f7474
3 changed files with 26 additions and 46 deletions

View File

@ -44,12 +44,12 @@ func (p *charParser) commitType() CommitType {
return p.commit return p.commit
} }
func (p *charParser) setIncludedBy(including parser, path []string) { func (p *charParser) setIncludedBy(includedBy parser, path []string) {
if stringsContain(path, p.name) { if stringsContain(path, p.name) {
panic(cannotIncludeParsers(p.name)) panic(cannotIncludeParsers(p.name))
} }
p.includedBy = append(p.includedBy, including) p.includedBy = append(p.includedBy, includedBy)
} }
func (p *charParser) cacheIncluded(*context, *Node) { func (p *charParser) cacheIncluded(*context, *Node) {
@ -91,8 +91,8 @@ func (p *charParser) parse(t Trace, c *context) {
t.Out1("success", string(tok)) t.Out1("success", string(tok))
n := newNode(p.name, p.commit, c.offset, c.offset+1) n := newNode(p.name, p.commit, c.offset, c.offset+1)
c.cache.set(c.offset, p.name, n) c.cache.set(c.offset, p.name, n)
for _, including := range p.includedBy { for _, includedBy := range p.includedBy {
including.cacheIncluded(c, n) includedBy.cacheIncluded(c, n)
} }
c.success(n) c.success(n)

View File

@ -10,7 +10,7 @@ type choiceParser struct {
name string name string
commit CommitType commit CommitType
elements []parser elements []parser
including []parser includedBy []parser
} }
func newChoice(name string, ct CommitType, elements []string) *choiceDefinition { func newChoice(name string, ct CommitType, elements []string) *choiceDefinition {
@ -23,8 +23,6 @@ func newChoice(name string, ct CommitType, elements []string) *choiceDefinition
func (d *choiceDefinition) nodeName() string { return d.name } func (d *choiceDefinition) nodeName() string { return d.name }
// could store and cache everything that it fulfils
func (d *choiceDefinition) parser(r *registry, path []string) (parser, error) { func (d *choiceDefinition) parser(r *registry, path []string) (parser, error) {
p, ok := r.parser(d.name) p, ok := r.parser(d.name)
if ok { if ok {
@ -72,12 +70,12 @@ func (d *choiceDefinition) commitType() CommitType {
func (p *choiceParser) nodeName() string { return p.name } func (p *choiceParser) nodeName() string { return p.name }
func (p *choiceParser) setIncludedBy(i parser, path []string) { func (p *choiceParser) setIncludedBy(includedBy parser, path []string) {
if stringsContain(path, p.name) { if stringsContain(path, p.name) {
return return
} }
p.including = append(p.including, i) p.includedBy = append(p.includedBy, includedBy)
} }
func (p *choiceParser) cacheIncluded(c *context, n *Node) { func (p *choiceParser) cacheIncluded(c *context, n *Node) {
@ -89,9 +87,8 @@ func (p *choiceParser) cacheIncluded(c *context, n *Node) {
nc.append(n) nc.append(n)
c.cache.set(nc.from, p.name, nc) c.cache.set(nc.from, p.name, nc)
// maybe it is enough to cache only those that are on the path for _, includedBy := range p.includedBy {
for _, i := range p.including { includedBy.cacheIncluded(c, nc)
i.cacheIncluded(c, nc)
} }
} }
@ -126,40 +123,24 @@ func (p *choiceParser) parse(t Trace, c *context) {
elements := p.elements elements := p.elements
var foundMatch bool var foundMatch bool
// TODO: this can be the entry point for a transformation that enables the
// processing of massive amounts of autogenerated rules in parallel in a
// continously, dynamically cached way. E.g. teach a machine that learns
// everything from a public library.
t.Out2("elements again")
for len(elements) > 0 { for len(elements) > 0 {
t.Out2("in the choice", c.offset, node.from, elements[0].nodeName())
elements[0].parse(t, c) elements[0].parse(t, c)
elements = elements[1:] elements = elements[1:]
c.offset = node.from c.offset = node.from
if !c.match || match && c.node.tokenLength() <= node.tokenLength() { if !c.match || match && c.node.tokenLength() <= node.tokenLength() {
t.Out2("skipping")
continue continue
} }
t.Out2("appending", c.node.tokenLength(), node.tokenLength(),
"\"", string(c.tokens[node.from:node.to]), "\"",
"\"", string(c.tokens[c.node.from:c.node.to]), "\"",
c.node.Name,
)
match = true match = true
foundMatch = true foundMatch = true
// node.clear() node = newNode(p.name, p.commit, c.offset, c.offset)
node = newNode(p.name, p.commit, c.offset, c.offset) // TODO: review caching conditions
node.append(c.node) node.append(c.node)
c.cache.set(node.from, p.name, node) c.cache.set(node.from, p.name, node)
for _, i := range p.including { for _, includedBy := range p.includedBy {
i.cacheIncluded(c, node) includedBy.cacheIncluded(c, node)
} }
// TODO: a simple break here can force PEG-style "priority" choices
} }
if !foundMatch { if !foundMatch {
@ -169,7 +150,6 @@ func (p *choiceParser) parse(t Trace, c *context) {
if match { if match {
t.Out1("choice, success") t.Out1("choice, success")
t.Out2("choice done", node.nodeLength())
c.success(node) c.success(node)
return return
} }

View File

@ -11,7 +11,7 @@ type sequenceParser struct {
commit CommitType commit CommitType
items []parser items []parser
ranges [][]int ranges [][]int
including []parser includedBy []parser
} }
func newSequence(name string, ct CommitType, items []SequenceItem) *sequenceDefinition { func newSequence(name string, ct CommitType, items []SequenceItem) *sequenceDefinition {
@ -91,12 +91,12 @@ func (d *sequenceDefinition) commitType() CommitType {
func (p *sequenceParser) nodeName() string { return p.name } func (p *sequenceParser) nodeName() string { return p.name }
func (p *sequenceParser) setIncludedBy(i parser, path []string) { func (p *sequenceParser) setIncludedBy(includedBy parser, path []string) {
if stringsContain(path, p.name) { if stringsContain(path, p.name) {
return return
} }
p.including = append(p.including, i) p.includedBy = append(p.includedBy, includedBy)
} }
func (p *sequenceParser) cacheIncluded(c *context, n *Node) { func (p *sequenceParser) cacheIncluded(c *context, n *Node) {
@ -108,8 +108,8 @@ func (p *sequenceParser) cacheIncluded(c *context, n *Node) {
nc.append(n) nc.append(n)
c.cache.set(nc.from, p.name, nc) c.cache.set(nc.from, p.name, nc)
for _, i := range p.including { for _, includedBy := range p.includedBy {
i.cacheIncluded(c, nc) includedBy.cacheIncluded(c, nc)
} }
} }
@ -175,8 +175,8 @@ func (p *sequenceParser) parse(t Trace, c *context) {
t.Out1("success, items parsed") t.Out1("success, items parsed")
c.cache.set(node.from, p.name, node) c.cache.set(node.from, p.name, node)
for _, i := range p.including { for _, includedBy := range p.includedBy {
i.cacheIncluded(c, node) includedBy.cacheIncluded(c, node)
} }
c.success(node) c.success(node)