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

View File

@ -10,7 +10,7 @@ type choiceParser struct {
name string
commit CommitType
elements []parser
including []parser
includedBy []parser
}
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 }
// could store and cache everything that it fulfils
func (d *choiceDefinition) parser(r *registry, path []string) (parser, error) {
p, ok := r.parser(d.name)
if ok {
@ -72,12 +70,12 @@ func (d *choiceDefinition) commitType() CommitType {
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) {
return
}
p.including = append(p.including, i)
p.includedBy = append(p.includedBy, includedBy)
}
func (p *choiceParser) cacheIncluded(c *context, n *Node) {
@ -89,9 +87,8 @@ func (p *choiceParser) cacheIncluded(c *context, n *Node) {
nc.append(n)
c.cache.set(nc.from, p.name, nc)
// maybe it is enough to cache only those that are on the path
for _, i := range p.including {
i.cacheIncluded(c, nc)
for _, includedBy := range p.includedBy {
includedBy.cacheIncluded(c, nc)
}
}
@ -126,40 +123,24 @@ func (p *choiceParser) parse(t Trace, c *context) {
elements := p.elements
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 {
t.Out2("in the choice", c.offset, node.from, elements[0].nodeName())
elements[0].parse(t, c)
elements = elements[1:]
c.offset = node.from
if !c.match || match && c.node.tokenLength() <= node.tokenLength() {
t.Out2("skipping")
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
foundMatch = true
// node.clear()
node = newNode(p.name, p.commit, c.offset, c.offset) // TODO: review caching conditions
node = newNode(p.name, p.commit, c.offset, c.offset)
node.append(c.node)
c.cache.set(node.from, p.name, node)
for _, i := range p.including {
i.cacheIncluded(c, node)
for _, includedBy := range p.includedBy {
includedBy.cacheIncluded(c, node)
}
// TODO: a simple break here can force PEG-style "priority" choices
}
if !foundMatch {
@ -169,7 +150,6 @@ func (p *choiceParser) parse(t Trace, c *context) {
if match {
t.Out1("choice, success")
t.Out2("choice done", node.nodeLength())
c.success(node)
return
}

View File

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