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 { type choiceBuilder struct {
name string name string
id int id int
commit CommitType commit CommitType
elements []builder elements []builder
includedBy []int
} }
func newChoice(name string, ct CommitType, elements []string) *choiceDefinition { 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) 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) parsers.set(d.id)
return setItemsIncludedBy(r, d.elements, includedBy, parsers) return setItemsIncludedBy(r, d.elements, includedBy, parsers)
} }
@ -203,6 +215,10 @@ func (b *choiceBuilder) build(c *context) ([]*Node, bool) {
return nil, false return nil, false
} }
for _, ib := range b.includedBy {
c.store.takeMatchLength(c.offset, ib, to)
}
var element builder var element builder
for _, e := range b.elements { for _, e := range b.elements {
elementTo, match, _ := c.store.getMatch(c.offset, e.nodeID()) elementTo, match, _ := c.store.getMatch(c.offset, e.nodeID())

View File

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

View File

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

View File

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

View File

@ -75,6 +75,40 @@ func (s *store) takeMatch(offset, id int) (int, bool) {
return to, found 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) { func (s *store) ensureOffset(offset int) {
if len(s.match) > offset { if len(s.match) > offset {
return return