diff --git a/choice.go b/choice.go index 07e4f88..e759f80 100644 --- a/choice.go +++ b/choice.go @@ -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()) diff --git a/json.parser b/json.parser index c7d40e8..de8c34d 100644 --- a/json.parser +++ b/json.parser @@ -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; diff --git a/mml_test.go b/mml_test.go index ac3cc16..db47e05 100644 --- a/mml_test.go +++ b/mml_test.go @@ -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"}, }, { diff --git a/sequence.go b/sequence.go index 4473644..623327f 100644 --- a/sequence.go +++ b/sequence.go @@ -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++ diff --git a/store.go b/store.go index 9d53797..e40b539 100644 --- a/store.go +++ b/store.go @@ -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