fix/ignore-pending-builders
This commit is contained in:
parent
3df7e79a0e
commit
dbe4a5302b
18
choice.go
18
choice.go
@ -9,10 +9,11 @@ type choiceParser struct {
|
||||
}
|
||||
|
||||
type choiceBuilder struct {
|
||||
name string
|
||||
id int
|
||||
commit CommitType
|
||||
options []builder
|
||||
name string
|
||||
id int
|
||||
commit CommitType
|
||||
options []builder
|
||||
generalizations []int
|
||||
}
|
||||
|
||||
func (p *choiceParser) nodeName() string { return p.name }
|
||||
@ -123,12 +124,18 @@ func (b *choiceBuilder) build(c *context) ([]*Node, bool) {
|
||||
|
||||
if parsed {
|
||||
c.results.dropMatchTo(c.offset, b.id, to)
|
||||
for _, g := range b.generalizations {
|
||||
c.results.dropMatchTo(c.offset, g, to)
|
||||
}
|
||||
} else {
|
||||
if c.results.pending(c.offset, b.id) {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
c.results.markPending(c.offset, b.id)
|
||||
for _, g := range b.generalizations {
|
||||
c.results.markPending(c.offset, g)
|
||||
}
|
||||
}
|
||||
|
||||
var option builder
|
||||
@ -142,6 +149,9 @@ func (b *choiceBuilder) build(c *context) ([]*Node, bool) {
|
||||
n, _ := option.build(c)
|
||||
if !parsed {
|
||||
c.results.unmarkPending(from, b.id)
|
||||
for _, g := range b.generalizations {
|
||||
c.results.unmarkPending(from, g)
|
||||
}
|
||||
}
|
||||
|
||||
if b.commit&Alias != 0 {
|
||||
|
@ -54,20 +54,11 @@ func (d *choiceDefinition) validate(r *registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *choiceDefinition) createBuilder() {
|
||||
d.cbuilder = &choiceBuilder{
|
||||
name: d.name,
|
||||
id: d.id,
|
||||
commit: d.commit,
|
||||
}
|
||||
}
|
||||
|
||||
func (d *choiceDefinition) initOptions(r *registry) {
|
||||
for _, o := range d.options {
|
||||
def := r.definition[o]
|
||||
d.optionDefs = append(d.optionDefs, def)
|
||||
def.init(r)
|
||||
d.cbuilder.options = append(d.cbuilder.options, def.builder())
|
||||
def.addGeneralization(d.id)
|
||||
}
|
||||
}
|
||||
@ -78,7 +69,6 @@ func (d *choiceDefinition) init(r *registry) {
|
||||
}
|
||||
|
||||
d.initialized = true
|
||||
d.createBuilder()
|
||||
d.initOptions(r)
|
||||
}
|
||||
|
||||
@ -119,7 +109,30 @@ func (d *choiceDefinition) parser() parser {
|
||||
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 {
|
||||
var chars []rune
|
||||
|
@ -186,19 +186,16 @@ select = "select" nl* "{" sep?
|
||||
go = "go" nl* function-application;
|
||||
defer = "defer" nl* function-application;
|
||||
|
||||
break = "break";
|
||||
continue = "continue";
|
||||
range-over-expression = symbol nl* "in" nl* (expression | range) | range;
|
||||
loop-expression:alias = expression | range-over-expression;
|
||||
loop = "for" ((nl* loop-expression)? nl* block | nl* block);
|
||||
|
||||
assignable:alias = symbol-indexer | simple-indexer | symbol;
|
||||
assign-capture = assignable (nl* "=")? nl* expression;
|
||||
assign-capture:alias = primary-expression (nl* "=")? nl* expression;
|
||||
assign-capture-list:alias = assign-capture (list-sep assign-capture)*;
|
||||
assign-set:alias = "set" nl* assign-capture;
|
||||
assign-equal:alias = assignable nl* "=" nl* expression;
|
||||
assign-group:alias = "set" nl* "(" list-sep? assign-capture-list? list-sep? ")";
|
||||
assignment = assign-set | assign-equal | assign-group;
|
||||
assign-eq:alias = primary-expression nl* "=" nl* expression;
|
||||
assign-group:alias = "set" nl* "(" (list-sep assign-capture-list)? list-sep? ")";
|
||||
assignment = assign-set | assign-eq | assign-group;
|
||||
|
||||
value-capture-fact:alias = symbol (nl* "=")? nl* expression;
|
||||
value-capture = value-capture-fact;
|
||||
@ -254,8 +251,6 @@ statement:alias = simple-statement
|
||||
| if
|
||||
| switch
|
||||
| select
|
||||
| break
|
||||
| continue
|
||||
| loop
|
||||
| definition
|
||||
| require
|
||||
|
92
mml_test.go
92
mml_test.go
@ -2118,12 +2118,9 @@ func TestMML(t *testing.T) {
|
||||
nodes: []*Node{{
|
||||
Name: "assignment",
|
||||
Nodes: []*Node{{
|
||||
Name: "assign-capture",
|
||||
Nodes: []*Node{{
|
||||
Name: "symbol",
|
||||
}, {
|
||||
Name: "symbol",
|
||||
}},
|
||||
Name: "symbol",
|
||||
}, {
|
||||
Name: "symbol",
|
||||
}},
|
||||
}},
|
||||
ignorePosition: true,
|
||||
@ -2133,37 +2130,96 @@ func TestMML(t *testing.T) {
|
||||
nodes: []*Node{{
|
||||
Name: "assignment",
|
||||
Nodes: []*Node{{
|
||||
Name: "assign-capture",
|
||||
Nodes: []*Node{{
|
||||
Name: "symbol",
|
||||
}, {
|
||||
Name: "symbol",
|
||||
}},
|
||||
Name: "symbol",
|
||||
}, {
|
||||
Name: "symbol",
|
||||
}},
|
||||
}},
|
||||
ignorePosition: true,
|
||||
}, {
|
||||
title: "assign, group",
|
||||
text: `set (
|
||||
a = b
|
||||
c d
|
||||
)`,
|
||||
a = b
|
||||
c d
|
||||
)`,
|
||||
nodes: []*Node{{
|
||||
Name: "assignment",
|
||||
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{{
|
||||
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{{
|
||||
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,
|
||||
|
@ -2669,9 +2669,9 @@ func TestMMLExp(t *testing.T) {
|
||||
}, {
|
||||
title: "assign, group",
|
||||
text: `set (
|
||||
a = b
|
||||
c d
|
||||
)`,
|
||||
a = b
|
||||
c d
|
||||
)`,
|
||||
nodes: []*Node{{
|
||||
Name: "assignment",
|
||||
Nodes: []*Node{{
|
||||
|
40
self/self.go
40
self/self.go
@ -96,12 +96,13 @@ type sequenceParser struct {
|
||||
allChars bool
|
||||
}
|
||||
type sequenceBuilder struct {
|
||||
name string
|
||||
id int
|
||||
commit CommitType
|
||||
items []builder
|
||||
ranges [][]int
|
||||
allChars bool
|
||||
name string
|
||||
id int
|
||||
commit CommitType
|
||||
items []builder
|
||||
ranges [][]int
|
||||
generalizations []int
|
||||
allChars bool
|
||||
}
|
||||
|
||||
func (p *sequenceParser) nodeName() string {
|
||||
@ -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
|
||||
} else if parsed {
|
||||
c.results.dropMatchTo(c.offset, b.id, to)
|
||||
for _, g := range b.generalizations {
|
||||
c.results.dropMatchTo(c.offset, g, to)
|
||||
}
|
||||
} else {
|
||||
if c.results.pending(c.offset, b.id) {
|
||||
return nil, false
|
||||
}
|
||||
c.results.markPending(c.offset, b.id)
|
||||
for _, g := range b.generalizations {
|
||||
c.results.markPending(c.offset, g)
|
||||
}
|
||||
}
|
||||
var (
|
||||
itemIndex int
|
||||
@ -229,6 +236,9 @@ func (b *sequenceBuilder) build(c *context) ([]*Node, bool) {
|
||||
}
|
||||
if !parsed {
|
||||
c.results.unmarkPending(from, b.id)
|
||||
for _, g := range b.generalizations {
|
||||
c.results.unmarkPending(from, g)
|
||||
}
|
||||
}
|
||||
if b.commit&Alias != 0 {
|
||||
return nodes, true
|
||||
@ -244,10 +254,11 @@ type choiceParser struct {
|
||||
generalizations []int
|
||||
}
|
||||
type choiceBuilder struct {
|
||||
name string
|
||||
id int
|
||||
commit CommitType
|
||||
options []builder
|
||||
name string
|
||||
id int
|
||||
commit CommitType
|
||||
options []builder
|
||||
generalizations []int
|
||||
}
|
||||
|
||||
func (p *choiceParser) nodeName() string {
|
||||
@ -346,11 +357,17 @@ func (b *choiceBuilder) build(c *context) ([]*Node, bool) {
|
||||
parsed := to > from
|
||||
if parsed {
|
||||
c.results.dropMatchTo(c.offset, b.id, to)
|
||||
for _, g := range b.generalizations {
|
||||
c.results.dropMatchTo(c.offset, g, to)
|
||||
}
|
||||
} else {
|
||||
if c.results.pending(c.offset, b.id) {
|
||||
return nil, false
|
||||
}
|
||||
c.results.markPending(c.offset, b.id)
|
||||
for _, g := range b.generalizations {
|
||||
c.results.markPending(c.offset, g)
|
||||
}
|
||||
}
|
||||
var option builder
|
||||
for _, o := range b.options {
|
||||
@ -362,6 +379,9 @@ func (b *choiceBuilder) build(c *context) ([]*Node, bool) {
|
||||
n, _ := option.build(c)
|
||||
if !parsed {
|
||||
c.results.unmarkPending(from, b.id)
|
||||
for _, g := range b.generalizations {
|
||||
c.results.unmarkPending(from, g)
|
||||
}
|
||||
}
|
||||
if b.commit&Alias != 0 {
|
||||
return n, true
|
||||
|
23
sequence.go
23
sequence.go
@ -11,12 +11,13 @@ type sequenceParser struct {
|
||||
}
|
||||
|
||||
type sequenceBuilder struct {
|
||||
name string
|
||||
id int
|
||||
commit CommitType
|
||||
items []builder
|
||||
ranges [][]int
|
||||
allChars bool
|
||||
name string
|
||||
id int
|
||||
commit CommitType
|
||||
items []builder
|
||||
ranges [][]int
|
||||
generalizations []int
|
||||
allChars bool
|
||||
}
|
||||
|
||||
func (p *sequenceParser) nodeName() string { return p.name }
|
||||
@ -123,12 +124,19 @@ func (b *sequenceBuilder) build(c *context) ([]*Node, bool) {
|
||||
}}, true
|
||||
} else if parsed {
|
||||
c.results.dropMatchTo(c.offset, b.id, to)
|
||||
for _, g := range b.generalizations {
|
||||
c.results.dropMatchTo(c.offset, g, to)
|
||||
}
|
||||
} else {
|
||||
if c.results.pending(c.offset, b.id) {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
c.results.markPending(c.offset, b.id)
|
||||
|
||||
for _, g := range b.generalizations {
|
||||
c.results.markPending(c.offset, g)
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
@ -170,6 +178,9 @@ func (b *sequenceBuilder) build(c *context) ([]*Node, bool) {
|
||||
|
||||
if !parsed {
|
||||
c.results.unmarkPending(from, b.id)
|
||||
for _, g := range b.generalizations {
|
||||
c.results.unmarkPending(from, g)
|
||||
}
|
||||
}
|
||||
|
||||
if b.commit&Alias != 0 {
|
||||
|
@ -92,22 +92,12 @@ func (d *sequenceDefinition) validate(r *registry) error {
|
||||
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) {
|
||||
allChars := true
|
||||
for _, item := range d.items {
|
||||
def := r.definition[item.Name]
|
||||
d.itemDefs = append(d.itemDefs, def)
|
||||
def.init(r)
|
||||
d.sbuilder.items = append(d.sbuilder.items, def.builder())
|
||||
if allChars {
|
||||
if _, isChar := def.(*charParser); !isChar {
|
||||
allChars = false
|
||||
@ -115,7 +105,6 @@ func (d *sequenceDefinition) initItems(r *registry) {
|
||||
}
|
||||
}
|
||||
|
||||
d.sbuilder.allChars = allChars
|
||||
d.allChars = allChars
|
||||
}
|
||||
|
||||
@ -126,7 +115,6 @@ func (d *sequenceDefinition) init(r *registry) {
|
||||
|
||||
d.initialized = true
|
||||
d.initRanges()
|
||||
d.createBuilder()
|
||||
d.initItems(r)
|
||||
}
|
||||
|
||||
@ -166,7 +154,33 @@ func (d *sequenceDefinition) parser() parser {
|
||||
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 {
|
||||
for i := range d.originalItems {
|
||||
|
Loading…
Reference in New Issue
Block a user