refactor choice parsing
This commit is contained in:
parent
c1c9a03ff4
commit
6a179f7474
8
char.go
8
char.go
@ -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)
|
||||
|
36
choice.go
36
choice.go
@ -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
|
||||
}
|
||||
|
14
sequence.go
14
sequence.go
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user