diff options
Diffstat (limited to 'src/pkg/ebnf/parser.go')
-rw-r--r-- | src/pkg/ebnf/parser.go | 24 |
1 files changed, 13 insertions, 11 deletions
diff --git a/src/pkg/ebnf/parser.go b/src/pkg/ebnf/parser.go index 818168e11..ede4f7073 100644 --- a/src/pkg/ebnf/parser.go +++ b/src/pkg/ebnf/parser.go @@ -85,6 +85,7 @@ func (p *parser) parseToken() *Token { } +// ParseTerm returns nil if no term was found. func (p *parser) parseTerm() (x Expression) { pos := p.pos @@ -95,7 +96,8 @@ func (p *parser) parseTerm() (x Expression) { case token.STRING: tok := p.parseToken() x = tok - if p.tok == token.ELLIPSIS { + const ellipsis = "…" // U+2026, the horizontal ellipsis character + if p.tok == token.ILLEGAL && p.lit == ellipsis { p.next() x = &Range{tok, p.parseToken()} } @@ -130,7 +132,8 @@ func (p *parser) parseSequence() Expression { // no need for a sequence if list.Len() < 2 switch len(list) { case 0: - return nil + p.errorExpected(p.pos, "term") + return &Bad{p.pos, "term expected"} case 1: return list[0] } @@ -143,20 +146,16 @@ func (p *parser) parseExpression() Expression { var list Alternative for { - if x := p.parseSequence(); x != nil { - list = append(list, x) - } + list = append(list, p.parseSequence()) if p.tok != token.OR { break } p.next() } + // len(list) > 0 // no need for an Alternative node if list.Len() < 2 - switch len(list) { - case 0: - return nil - case 1: + if len(list) == 1 { return list[0] } @@ -167,7 +166,10 @@ func (p *parser) parseExpression() Expression { func (p *parser) parseProduction() *Production { name := p.parseIdentifier() p.expect(token.ASSIGN) - expr := p.parseExpression() + var expr Expression + if p.tok != token.PERIOD { + expr = p.parseExpression() + } p.expect(token.PERIOD) return &Production{name, expr} } @@ -177,7 +179,7 @@ func (p *parser) parse(fset *token.FileSet, filename string, src []byte) Grammar // initialize parser p.fset = fset p.ErrorVector.Reset() - p.scanner.Init(fset.AddFile(filename, fset.Base(), len(src)), src, p, 0) + p.scanner.Init(fset.AddFile(filename, fset.Base(), len(src)), src, p, scanner.AllowIllegalChars) p.next() // initializes pos, tok, lit grammar := make(Grammar) |