remove included during build

This commit is contained in:
Arpad Ryszka 2017-07-29 20:04:22 +02:00
parent 73585dd07d
commit b1969e802f
5 changed files with 83 additions and 17 deletions

View File

@ -18,10 +18,11 @@ type choiceParser struct {
}
type choiceBuilder struct {
name string
id int
commit CommitType
elements []builder
name string
id int
commit CommitType
elements []builder
includedBy []int
}
func newChoice(name string, ct CommitType, elements []string) *choiceDefinition {
@ -66,6 +67,17 @@ func (d *choiceDefinition) setIncludedBy(r *registry, includedBy int, parsers *i
}
d.includedBy = appendIfMissing(d.includedBy, includedBy)
if d.cbuilder == nil {
d.cbuilder = &choiceBuilder{
name: d.name,
id: d.id,
commit: d.commit,
}
}
d.cbuilder.includedBy = appendIfMissing(d.cbuilder.includedBy, includedBy)
parsers.set(d.id)
return setItemsIncludedBy(r, d.elements, includedBy, parsers)
}
@ -203,6 +215,10 @@ func (b *choiceBuilder) build(c *context) ([]*Node, bool) {
return nil, false
}
for _, ib := range b.includedBy {
c.store.takeMatchLength(c.offset, ib, to)
}
var element builder
for _, e := range b.elements {
elementTo, match, _ := c.store.getMatch(c.offset, e.nodeID())

View File

@ -1,12 +1,12 @@
// JSON (http://www.json.org)
ws:ws = [ \b\f\n\r\t];
ws:alias = [ \b\f\n\r\t];
true = "true";
false = "false";
null = "null";
string:nows = "\"" ([^\\"\b\f\n\r\t] | "\\" (["\\/bfnrt] | "u" [0-9a-f]{4}))* "\"";
number:nows = "-"? ("0" | [1-9][0-9]*) ("." [0-9]+)? ([eE] [+\-]? [0-9]+)?;
entry = string ":" value;
object = "{" (entry ("," entry)*)? "}";
array = "[" (value ("," value)*)? "]";
string = "\"" ([^\\"\b\f\n\r\t] | "\\" (["\\/bfnrt] | "u" [0-9a-f]{4}))* "\"";
number = "-"? ("0" | [1-9][0-9]*) ("." [0-9]+)? ([eE] [+\-]? [0-9]+)?;
entry = string ws* ":" ws* value;
object = "{" ws* (entry ws* ("," ws* entry)*)? ws* "}";
array = "[" ws* (value ws* ("," ws* value)*)? ws* "]";
value:alias = true | false | null | string | number | object | array;
json:root = value;

View File

@ -9,7 +9,7 @@ import (
)
func TestMML(t *testing.T) {
test(t, "mml.parser", "mml", []testItem{{
testTrace(t, "mml.parser", "mml", 1, []testItem{{
msg: "empty",
node: &Node{Name: "mml"},
}, {

View File

@ -20,11 +20,12 @@ type sequenceParser struct {
}
type sequenceBuilder struct {
name string
id int
commit CommitType
items []builder
ranges [][]int
name string
id int
commit CommitType
items []builder
ranges [][]int
includedBy []int
}
func newSequence(name string, ct CommitType, items []SequenceItem) *sequenceDefinition {
@ -87,6 +88,17 @@ func (d *sequenceDefinition) setIncludedBy(r *registry, includedBy int, parsers
}
d.includedBy = appendIfMissing(d.includedBy, includedBy)
if d.sbuilder == nil {
d.sbuilder = &sequenceBuilder{
name: d.name,
id: d.id,
commit: d.commit,
}
}
d.sbuilder.includedBy = appendIfMissing(d.sbuilder.includedBy, includedBy)
if !d.includeItems() {
return nil
}
@ -227,6 +239,10 @@ func (b *sequenceBuilder) build(c *context) ([]*Node, bool) {
return nil, false
}
for _, ib := range b.includedBy {
c.store.takeMatchLength(c.offset, ib, to)
}
from := c.offset
var (
itemIndex int
@ -239,7 +255,7 @@ func (b *sequenceBuilder) build(c *context) ([]*Node, bool) {
n, ok := b.items[itemIndex].build(c)
if !ok {
if currentCount < b.ranges[itemIndex][0] {
panic("damaged parse result")
panic(b.name + ": damaged parse result")
}
itemIndex++

View File

@ -75,6 +75,40 @@ func (s *store) takeMatch(offset, id int) (int, bool) {
return to, found
}
func (s *store) takeMatchLength(offset, id, to int) (int, bool) {
if s.hasNoMatch(offset, id) {
return 0, false
}
if len(s.match) <= offset {
return 0, false
}
var (
found bool
// index int
)
for i := 0; i < len(s.match[offset]); i += 2 {
if s.match[offset][i] != id {
continue
}
found = true
if s.match[offset][i+1] == to {
s.match[offset][i] = -1
return to, true
//eindex = i
}
}
if found {
// s.match[offset][index] = -1
}
return to, found
}
func (s *store) ensureOffset(offset int) {
if len(s.match) > offset {
return