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
|
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)
|
||||||
|
36
choice.go
36
choice.go
@ -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
|
||||||
}
|
}
|
||||||
|
14
sequence.go
14
sequence.go
@ -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)
|
||||||
|
Loading…
Reference in New Issue
Block a user