check if all parsers are referenced
This commit is contained in:
parent
b20ed19b4e
commit
005da7cd1f
@ -29,11 +29,15 @@ func (p *charParser) setName(n string) { p.name = n }
|
|||||||
func (p *charParser) setID(id int) { p.id = id }
|
func (p *charParser) setID(id int) { p.id = id }
|
||||||
func (p *charParser) setCommitType(ct CommitType) {}
|
func (p *charParser) setCommitType(ct CommitType) {}
|
||||||
func (p *charParser) preinit() {}
|
func (p *charParser) preinit() {}
|
||||||
func (p *charParser) validate(*registry) error { return nil }
|
|
||||||
func (p *charParser) init(*registry) {}
|
func (p *charParser) init(*registry) {}
|
||||||
func (p *charParser) addGeneralization(int) {}
|
func (p *charParser) addGeneralization(int) {}
|
||||||
func (p *charParser) parser() parser { return p }
|
func (p *charParser) parser() parser { return p }
|
||||||
|
|
||||||
|
func (p *charParser) validate(r *registry) error {
|
||||||
|
r.setRef(p)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (p *charParser) builder() builder {
|
func (p *charParser) builder() builder {
|
||||||
return &charBuilder{
|
return &charBuilder{
|
||||||
id: p.id,
|
id: p.id,
|
||||||
|
|||||||
@ -40,6 +40,7 @@ func (d *choiceDefinition) validate(r *registry) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
d.validated = true
|
d.validated = true
|
||||||
|
r.setRef(d)
|
||||||
for i := range d.options {
|
for i := range d.options {
|
||||||
o, ok := r.definition[d.options[i]]
|
o, ok := r.definition[d.options[i]]
|
||||||
if !ok {
|
if !ok {
|
||||||
|
|||||||
@ -281,7 +281,10 @@ receive-assignment-equal = assignable nl* "=" nl* receive-expression;
|
|||||||
receive-capture:alias = symbol-expression nl* ("=" nl*)? receive-expression;
|
receive-capture:alias = symbol-expression nl* ("=" nl*)? receive-expression;
|
||||||
receive-definition = "let" nl* receive-capture;
|
receive-definition = "let" nl* receive-capture;
|
||||||
receive-mutable-definition = "let" nl* "~" nl* receive-capture;
|
receive-mutable-definition = "let" nl* "~" nl* receive-capture;
|
||||||
receive-statement:alias = receive-assignment | receive-definition;
|
receive-statement:alias = receive-assignment
|
||||||
|
| receive-assignment-equal
|
||||||
|
| receive-definition
|
||||||
|
| receive-mutable-definition;
|
||||||
send-call:alias = "send" "(" (nl | ",")* expression list-sep expression (nl | ",")* ")";
|
send-call:alias = "send" "(" (nl | ",")* expression list-sep expression (nl | ",")* ")";
|
||||||
send-op:alias = primary-expression "<-" expression;
|
send-op:alias = primary-expression "<-" expression;
|
||||||
send-call-group:alias = "(" nl* send nl* ")";
|
send-call-group:alias = "(" nl* send nl* ")";
|
||||||
@ -496,7 +499,8 @@ statement:alias = send
|
|||||||
| expression
|
| expression
|
||||||
| type-alias
|
| type-alias
|
||||||
| type-constraint
|
| type-constraint
|
||||||
| statement-group;
|
| statement-group
|
||||||
|
| type-expression;
|
||||||
shebang-command = [^\n]*;
|
shebang-command = [^\n]*;
|
||||||
shebang = "#!" shebang-command "\n";
|
shebang = "#!" shebang-command "\n";
|
||||||
sep:alias = (";" | "\n") (nl | ";")*;
|
sep:alias = (";" | "\n") (nl | ";")*;
|
||||||
|
|||||||
@ -110,7 +110,6 @@ operand1:alias = operand0 | binary0;
|
|||||||
operand2:alias = operand1 | binary1;
|
operand2:alias = operand1 | binary1;
|
||||||
operand3:alias = operand2 | binary2;
|
operand3:alias = operand2 | binary2;
|
||||||
operand4:alias = operand3 | binary3;
|
operand4:alias = operand3 | binary3;
|
||||||
operand5:alias = operand4 | binary4;
|
|
||||||
binary0 = operand0 (nl* binary-op0 nl* operand0)+;
|
binary0 = operand0 (nl* binary-op0 nl* operand0)+;
|
||||||
binary1 = operand1 (nl* binary-op1 nl* operand1)+;
|
binary1 = operand1 (nl* binary-op1 nl* operand1)+;
|
||||||
binary2 = operand2 (nl* binary-op2 nl* operand2)+;
|
binary2 = operand2 (nl* binary-op2 nl* operand2)+;
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
ws:ws = " " | "\b" | "\f" | "\r" | "\t" | "\v";
|
ws:ws = " " | "\b" | "\f" | "\r" | "\t" | "\v";
|
||||||
wsc:ws = comment;
|
wsc:ws = comment;
|
||||||
nl:alias = "\n";
|
nl:alias = "\n";
|
||||||
wsep:alias = ws | nl;
|
|
||||||
line-comment-content:nows = [^\n]*;
|
line-comment-content:nows = [^\n]*;
|
||||||
line-comment:alias:nows = "//" line-comment-content;
|
line-comment:alias:nows = "//" line-comment-content;
|
||||||
block-comment-content:nows = ([^*] | "*" [^/])*;
|
block-comment-content:nows = ([^*] | "*" [^/])*;
|
||||||
@ -112,7 +111,6 @@ operand1:alias = operand0 | binary0;
|
|||||||
operand2:alias = operand1 | binary1;
|
operand2:alias = operand1 | binary1;
|
||||||
operand3:alias = operand2 | binary2;
|
operand3:alias = operand2 | binary2;
|
||||||
operand4:alias = operand3 | binary3;
|
operand4:alias = operand3 | binary3;
|
||||||
operand5:alias = operand4 | binary4;
|
|
||||||
binary0 = operand0 (nl* binary-op0 nl* operand0)+;
|
binary0 = operand0 (nl* binary-op0 nl* operand0)+;
|
||||||
binary1 = operand1 (nl* binary-op1 nl* operand1)+;
|
binary1 = operand1 (nl* binary-op1 nl* operand1)+;
|
||||||
binary2 = operand2 (nl* binary-op2 nl* operand2)+;
|
binary2 = operand2 (nl* binary-op2 nl* operand2)+;
|
||||||
|
|||||||
@ -6,5 +6,5 @@ symbol:nows = ([^\\ \n\t\b\f\r\v\"()\[\]#] | "\\" .)+;
|
|||||||
list-form:alias = "(" expression* ")" | "[" expression* "]";
|
list-form:alias = "(" expression* ")" | "[" expression* "]";
|
||||||
list = list-form;
|
list = list-form;
|
||||||
vector = "#" list-form;
|
vector = "#" list-form;
|
||||||
expression:alias = number | string | symbol | list;
|
expression:alias = number | string | symbol | list | vector;
|
||||||
scheme = expression*;
|
scheme = expression*;
|
||||||
|
|||||||
25
registry.go
25
registry.go
@ -4,11 +4,13 @@ type registry struct {
|
|||||||
idSeed int
|
idSeed int
|
||||||
definition map[string]definition
|
definition map[string]definition
|
||||||
definitions []definition
|
definitions []definition
|
||||||
|
referenced map[string]bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func newRegistry(defs ...definition) *registry {
|
func newRegistry(defs ...definition) *registry {
|
||||||
r := ®istry{
|
r := ®istry{
|
||||||
definition: make(map[string]definition),
|
definition: make(map[string]definition),
|
||||||
|
referenced: make(map[string]bool),
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, def := range defs {
|
for _, def := range defs {
|
||||||
@ -31,3 +33,26 @@ func (r *registry) setDefinition(d definition) error {
|
|||||||
r.definitions = append(r.definitions, d)
|
r.definitions = append(r.definitions, d)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *registry) setRef(d definition) {
|
||||||
|
if d.commitType()&userDefined == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
r.referenced[d.nodeName()] = true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *registry) unreferenced() []string {
|
||||||
|
var u []string
|
||||||
|
for _, def := range r.definitions {
|
||||||
|
if def.commitType()&userDefined == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if !r.referenced[def.nodeName()] {
|
||||||
|
u = append(u, def.nodeName())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return u
|
||||||
|
}
|
||||||
|
|||||||
@ -79,6 +79,7 @@ func (d *sequenceDefinition) validate(r *registry) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
d.validated = true
|
d.validated = true
|
||||||
|
r.setRef(d)
|
||||||
for i := range d.items {
|
for i := range d.items {
|
||||||
ii, ok := r.definition[d.items[i].Name]
|
ii, ok := r.definition[d.items[i].Name]
|
||||||
if !ok {
|
if !ok {
|
||||||
|
|||||||
14
syntax.go
14
syntax.go
@ -430,6 +430,20 @@ func (s *Syntax) Init() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u := s.registry.unreferenced()
|
||||||
|
if len(u) > 0 {
|
||||||
|
var err error
|
||||||
|
us := strings.Join(u, ", ")
|
||||||
|
if len(us) > 108 {
|
||||||
|
err = fmt.Errorf("unrefenced parsers (%d)", len(u))
|
||||||
|
} else {
|
||||||
|
err = fmt.Errorf("unrefenced parsers (%d): %s", len(u), us)
|
||||||
|
}
|
||||||
|
|
||||||
|
s.errInitFailed = err
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
for i := range s.keywords {
|
for i := range s.keywords {
|
||||||
s.keywords[i].init(s.registry)
|
s.keywords[i].init(s.registry)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -79,6 +79,12 @@ func TestValidation(t *testing.T) {
|
|||||||
t.Error("failed to fail")
|
t.Error("failed to fail")
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("unreferenced parser", func(t *testing.T) {
|
||||||
|
if _, err := openSyntaxString(`foo = "foo"; bar:root = "bar"`); err == nil {
|
||||||
|
t.Error("failed to fail")
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestInit(t *testing.T) {
|
func TestInit(t *testing.T) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user