fix/ignore-pending-builders

This commit is contained in:
Arpad Ryszka 2018-08-19 22:40:01 +02:00
parent 3df7e79a0e
commit dbe4a5302b
9 changed files with 194 additions and 75 deletions

View File

@ -13,6 +13,7 @@ type choiceBuilder struct {
id int id int
commit CommitType commit CommitType
options []builder options []builder
generalizations []int
} }
func (p *choiceParser) nodeName() string { return p.name } func (p *choiceParser) nodeName() string { return p.name }
@ -123,12 +124,18 @@ func (b *choiceBuilder) build(c *context) ([]*Node, bool) {
if parsed { if parsed {
c.results.dropMatchTo(c.offset, b.id, to) c.results.dropMatchTo(c.offset, b.id, to)
for _, g := range b.generalizations {
c.results.dropMatchTo(c.offset, g, to)
}
} else { } else {
if c.results.pending(c.offset, b.id) { if c.results.pending(c.offset, b.id) {
return nil, false return nil, false
} }
c.results.markPending(c.offset, b.id) c.results.markPending(c.offset, b.id)
for _, g := range b.generalizations {
c.results.markPending(c.offset, g)
}
} }
var option builder var option builder
@ -142,6 +149,9 @@ func (b *choiceBuilder) build(c *context) ([]*Node, bool) {
n, _ := option.build(c) n, _ := option.build(c)
if !parsed { if !parsed {
c.results.unmarkPending(from, b.id) c.results.unmarkPending(from, b.id)
for _, g := range b.generalizations {
c.results.unmarkPending(from, g)
}
} }
if b.commit&Alias != 0 { if b.commit&Alias != 0 {

View File

@ -54,20 +54,11 @@ func (d *choiceDefinition) validate(r *registry) error {
return nil return nil
} }
func (d *choiceDefinition) createBuilder() {
d.cbuilder = &choiceBuilder{
name: d.name,
id: d.id,
commit: d.commit,
}
}
func (d *choiceDefinition) initOptions(r *registry) { func (d *choiceDefinition) initOptions(r *registry) {
for _, o := range d.options { for _, o := range d.options {
def := r.definition[o] def := r.definition[o]
d.optionDefs = append(d.optionDefs, def) d.optionDefs = append(d.optionDefs, def)
def.init(r) def.init(r)
d.cbuilder.options = append(d.cbuilder.options, def.builder())
def.addGeneralization(d.id) def.addGeneralization(d.id)
} }
} }
@ -78,7 +69,6 @@ func (d *choiceDefinition) init(r *registry) {
} }
d.initialized = true d.initialized = true
d.createBuilder()
d.initOptions(r) d.initOptions(r)
} }
@ -119,7 +109,30 @@ func (d *choiceDefinition) parser() parser {
return d.cparser return d.cparser
} }
func (d *choiceDefinition) builder() builder { return d.cbuilder } func (d *choiceDefinition) createBuilder() {
d.cbuilder = &choiceBuilder{
name: d.name,
id: d.id,
commit: d.commit,
generalizations: d.generalizations,
}
}
func (d *choiceDefinition) createOptionBuilders() {
for _, def := range d.optionDefs {
option := def.builder()
d.cbuilder.options = append(d.cbuilder.options, option)
}
}
func (d *choiceDefinition) builder() builder {
if d.cbuilder != nil {
return d.cbuilder
}
d.createBuilder()
d.createOptionBuilders()
return d.cbuilder
}
func (d *choiceDefinition) format(r *registry, f formatFlags) string { func (d *choiceDefinition) format(r *registry, f formatFlags) string {
var chars []rune var chars []rune

View File

@ -186,19 +186,16 @@ select = "select" nl* "{" sep?
go = "go" nl* function-application; go = "go" nl* function-application;
defer = "defer" nl* function-application; defer = "defer" nl* function-application;
break = "break";
continue = "continue";
range-over-expression = symbol nl* "in" nl* (expression | range) | range; range-over-expression = symbol nl* "in" nl* (expression | range) | range;
loop-expression:alias = expression | range-over-expression; loop-expression:alias = expression | range-over-expression;
loop = "for" ((nl* loop-expression)? nl* block | nl* block); loop = "for" ((nl* loop-expression)? nl* block | nl* block);
assignable:alias = symbol-indexer | simple-indexer | symbol; assign-capture:alias = primary-expression (nl* "=")? nl* expression;
assign-capture = assignable (nl* "=")? nl* expression;
assign-capture-list:alias = assign-capture (list-sep assign-capture)*; assign-capture-list:alias = assign-capture (list-sep assign-capture)*;
assign-set:alias = "set" nl* assign-capture; assign-set:alias = "set" nl* assign-capture;
assign-equal:alias = assignable nl* "=" nl* expression; assign-eq:alias = primary-expression nl* "=" nl* expression;
assign-group:alias = "set" nl* "(" list-sep? assign-capture-list? list-sep? ")"; assign-group:alias = "set" nl* "(" (list-sep assign-capture-list)? list-sep? ")";
assignment = assign-set | assign-equal | assign-group; assignment = assign-set | assign-eq | assign-group;
value-capture-fact:alias = symbol (nl* "=")? nl* expression; value-capture-fact:alias = symbol (nl* "=")? nl* expression;
value-capture = value-capture-fact; value-capture = value-capture-fact;
@ -254,8 +251,6 @@ statement:alias = simple-statement
| if | if
| switch | switch
| select | select
| break
| continue
| loop | loop
| definition | definition
| require | require

File diff suppressed because one or more lines are too long

View File

@ -2117,30 +2117,24 @@ func TestMML(t *testing.T) {
text: "set a = b", text: "set a = b",
nodes: []*Node{{ nodes: []*Node{{
Name: "assignment", Name: "assignment",
Nodes: []*Node{{
Name: "assign-capture",
Nodes: []*Node{{ Nodes: []*Node{{
Name: "symbol", Name: "symbol",
}, { }, {
Name: "symbol", Name: "symbol",
}}, }},
}}, }},
}},
ignorePosition: true, ignorePosition: true,
}, { }, {
title: "assign, set", title: "assign, set",
text: "set a b", text: "set a b",
nodes: []*Node{{ nodes: []*Node{{
Name: "assignment", Name: "assignment",
Nodes: []*Node{{
Name: "assign-capture",
Nodes: []*Node{{ Nodes: []*Node{{
Name: "symbol", Name: "symbol",
}, { }, {
Name: "symbol", Name: "symbol",
}}, }},
}}, }},
}},
ignorePosition: true, ignorePosition: true,
}, { }, {
title: "assign, group", title: "assign, group",
@ -2151,19 +2145,81 @@ func TestMML(t *testing.T) {
nodes: []*Node{{ nodes: []*Node{{
Name: "assignment", Name: "assignment",
Nodes: []*Node{{ Nodes: []*Node{{
Name: "assign-capture", Name: "symbol",
}, {
Name: "symbol",
}, {
Name: "symbol",
}, {
Name: "symbol",
}},
}},
ignorePosition: true,
}, {
title: "assign to struct field",
text: "set a.b c",
nodes: []*Node{{
Name: "assignment",
Nodes: []*Node{{
Name: "symbol-indexer",
Nodes: []*Node{{ Nodes: []*Node{{
Name: "symbol", Name: "symbol",
}, { }, {
Name: "symbol", Name: "symbol",
}}, }},
}, { }, {
Name: "assign-capture", Name: "symbol",
}},
}},
ignorePosition: true,
}, {
title: "indexer",
text: "set a[1] 42",
nodes: []*Node{{
Name: "assignment",
Nodes: []*Node{{
Name: "expression-indexer",
Nodes: []*Node{{ Nodes: []*Node{{
Name: "symbol", Name: "symbol",
}, { }, {
Name: "symbol", Name: "int",
}}, }},
}, {
Name: "int",
}},
}},
ignorePosition: true,
}, {
title: "indexer, eq",
text: "a[1] = 42",
nodes: []*Node{{
Name: "assignment",
Nodes: []*Node{{
Name: "expression-indexer",
Nodes: []*Node{{
Name: "symbol",
}, {
Name: "int",
}},
}, {
Name: "int",
}},
}},
ignorePosition: true,
}, {
title: "indexer, set, eq",
text: "set a[1] = 42",
nodes: []*Node{{
Name: "assignment",
Nodes: []*Node{{
Name: "expression-indexer",
Nodes: []*Node{{
Name: "symbol",
}, {
Name: "int",
}},
}, {
Name: "int",
}}, }},
}}, }},
ignorePosition: true, ignorePosition: true,

View File

@ -101,6 +101,7 @@ type sequenceBuilder struct {
commit CommitType commit CommitType
items []builder items []builder
ranges [][]int ranges [][]int
generalizations []int
allChars bool allChars bool
} }
@ -191,11 +192,17 @@ func (b *sequenceBuilder) build(c *context) ([]*Node, bool) {
return []*Node{{Name: b.name, From: from, To: to, tokens: c.tokens}}, true return []*Node{{Name: b.name, From: from, To: to, tokens: c.tokens}}, true
} else if parsed { } else if parsed {
c.results.dropMatchTo(c.offset, b.id, to) c.results.dropMatchTo(c.offset, b.id, to)
for _, g := range b.generalizations {
c.results.dropMatchTo(c.offset, g, to)
}
} else { } else {
if c.results.pending(c.offset, b.id) { if c.results.pending(c.offset, b.id) {
return nil, false return nil, false
} }
c.results.markPending(c.offset, b.id) c.results.markPending(c.offset, b.id)
for _, g := range b.generalizations {
c.results.markPending(c.offset, g)
}
} }
var ( var (
itemIndex int itemIndex int
@ -229,6 +236,9 @@ func (b *sequenceBuilder) build(c *context) ([]*Node, bool) {
} }
if !parsed { if !parsed {
c.results.unmarkPending(from, b.id) c.results.unmarkPending(from, b.id)
for _, g := range b.generalizations {
c.results.unmarkPending(from, g)
}
} }
if b.commit&Alias != 0 { if b.commit&Alias != 0 {
return nodes, true return nodes, true
@ -248,6 +258,7 @@ type choiceBuilder struct {
id int id int
commit CommitType commit CommitType
options []builder options []builder
generalizations []int
} }
func (p *choiceParser) nodeName() string { func (p *choiceParser) nodeName() string {
@ -346,11 +357,17 @@ func (b *choiceBuilder) build(c *context) ([]*Node, bool) {
parsed := to > from parsed := to > from
if parsed { if parsed {
c.results.dropMatchTo(c.offset, b.id, to) c.results.dropMatchTo(c.offset, b.id, to)
for _, g := range b.generalizations {
c.results.dropMatchTo(c.offset, g, to)
}
} else { } else {
if c.results.pending(c.offset, b.id) { if c.results.pending(c.offset, b.id) {
return nil, false return nil, false
} }
c.results.markPending(c.offset, b.id) c.results.markPending(c.offset, b.id)
for _, g := range b.generalizations {
c.results.markPending(c.offset, g)
}
} }
var option builder var option builder
for _, o := range b.options { for _, o := range b.options {
@ -362,6 +379,9 @@ func (b *choiceBuilder) build(c *context) ([]*Node, bool) {
n, _ := option.build(c) n, _ := option.build(c)
if !parsed { if !parsed {
c.results.unmarkPending(from, b.id) c.results.unmarkPending(from, b.id)
for _, g := range b.generalizations {
c.results.unmarkPending(from, g)
}
} }
if b.commit&Alias != 0 { if b.commit&Alias != 0 {
return n, true return n, true

View File

@ -16,6 +16,7 @@ type sequenceBuilder struct {
commit CommitType commit CommitType
items []builder items []builder
ranges [][]int ranges [][]int
generalizations []int
allChars bool allChars bool
} }
@ -123,12 +124,19 @@ func (b *sequenceBuilder) build(c *context) ([]*Node, bool) {
}}, true }}, true
} else if parsed { } else if parsed {
c.results.dropMatchTo(c.offset, b.id, to) c.results.dropMatchTo(c.offset, b.id, to)
for _, g := range b.generalizations {
c.results.dropMatchTo(c.offset, g, to)
}
} else { } else {
if c.results.pending(c.offset, b.id) { if c.results.pending(c.offset, b.id) {
return nil, false return nil, false
} }
c.results.markPending(c.offset, b.id) c.results.markPending(c.offset, b.id)
for _, g := range b.generalizations {
c.results.markPending(c.offset, g)
}
} }
var ( var (
@ -170,6 +178,9 @@ func (b *sequenceBuilder) build(c *context) ([]*Node, bool) {
if !parsed { if !parsed {
c.results.unmarkPending(from, b.id) c.results.unmarkPending(from, b.id)
for _, g := range b.generalizations {
c.results.unmarkPending(from, g)
}
} }
if b.commit&Alias != 0 { if b.commit&Alias != 0 {

View File

@ -92,22 +92,12 @@ func (d *sequenceDefinition) validate(r *registry) error {
return nil return nil
} }
func (d *sequenceDefinition) createBuilder() {
d.sbuilder = &sequenceBuilder{
name: d.name,
id: d.id,
commit: d.commit,
ranges: d.ranges,
}
}
func (d *sequenceDefinition) initItems(r *registry) { func (d *sequenceDefinition) initItems(r *registry) {
allChars := true allChars := true
for _, item := range d.items { for _, item := range d.items {
def := r.definition[item.Name] def := r.definition[item.Name]
d.itemDefs = append(d.itemDefs, def) d.itemDefs = append(d.itemDefs, def)
def.init(r) def.init(r)
d.sbuilder.items = append(d.sbuilder.items, def.builder())
if allChars { if allChars {
if _, isChar := def.(*charParser); !isChar { if _, isChar := def.(*charParser); !isChar {
allChars = false allChars = false
@ -115,7 +105,6 @@ func (d *sequenceDefinition) initItems(r *registry) {
} }
} }
d.sbuilder.allChars = allChars
d.allChars = allChars d.allChars = allChars
} }
@ -126,7 +115,6 @@ func (d *sequenceDefinition) init(r *registry) {
d.initialized = true d.initialized = true
d.initRanges() d.initRanges()
d.createBuilder()
d.initItems(r) d.initItems(r)
} }
@ -166,7 +154,33 @@ func (d *sequenceDefinition) parser() parser {
return d.sparser return d.sparser
} }
func (d *sequenceDefinition) builder() builder { return d.sbuilder } func (d *sequenceDefinition) createBuilder() {
d.sbuilder = &sequenceBuilder{
name: d.name,
id: d.id,
commit: d.commit,
ranges: d.ranges,
allChars: d.allChars,
generalizations: d.generalizations,
}
}
func (d *sequenceDefinition) createItemBuilders() {
for _, item := range d.itemDefs {
pi := item.builder()
d.sbuilder.items = append(d.sbuilder.items, pi)
}
}
func (d *sequenceDefinition) builder() builder {
if d.sbuilder != nil {
return d.sbuilder
}
d.createBuilder()
d.createItemBuilders()
return d.sbuilder
}
func (d *sequenceDefinition) isCharSequence(r *registry) bool { func (d *sequenceDefinition) isCharSequence(r *registry) bool {
for i := range d.originalItems { for i := range d.originalItems {