diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2011-09-16 15:47:21 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2011-09-16 15:47:21 +0000 |
commit | adb0401dac41c81571722312d4586b2693f95aa6 (patch) | |
tree | ea2b52e3c258d6b6d9356977c683c7f72a4a5fd5 /libgo/go/ebnf/parser.go | |
parent | 5548ca3540bccbc908a45942896d635ea5f1c23f (diff) | |
download | gcc-adb0401dac41c81571722312d4586b2693f95aa6.zip gcc-adb0401dac41c81571722312d4586b2693f95aa6.tar.gz gcc-adb0401dac41c81571722312d4586b2693f95aa6.tar.bz2 |
Update Go library to r60.
From-SVN: r178910
Diffstat (limited to 'libgo/go/ebnf/parser.go')
-rw-r--r-- | libgo/go/ebnf/parser.go | 37 |
1 files changed, 13 insertions, 24 deletions
diff --git a/libgo/go/ebnf/parser.go b/libgo/go/ebnf/parser.go index 818168e..ef2fac0 100644 --- a/libgo/go/ebnf/parser.go +++ b/libgo/go/ebnf/parser.go @@ -11,7 +11,6 @@ import ( "strconv" ) - type parser struct { fset *token.FileSet scanner.ErrorVector @@ -21,7 +20,6 @@ type parser struct { lit string // token literal } - func (p *parser) next() { p.pos, p.tok, p.lit = p.scanner.Scan() if p.tok.IsKeyword() { @@ -31,12 +29,10 @@ func (p *parser) next() { } } - func (p *parser) error(pos token.Pos, msg string) { p.Error(p.fset.Position(pos), msg) } - func (p *parser) errorExpected(pos token.Pos, msg string) { msg = "expected " + msg if pos == p.pos { @@ -50,7 +46,6 @@ func (p *parser) errorExpected(pos token.Pos, msg string) { p.error(pos, msg) } - func (p *parser) expect(tok token.Token) token.Pos { pos := p.pos if p.tok != tok { @@ -60,7 +55,6 @@ func (p *parser) expect(tok token.Token) token.Pos { return pos } - func (p *parser) parseIdentifier() *Name { pos := p.pos name := p.lit @@ -68,7 +62,6 @@ func (p *parser) parseIdentifier() *Name { return &Name{pos, name} } - func (p *parser) parseToken() *Token { pos := p.pos value := "" @@ -84,7 +77,7 @@ func (p *parser) parseToken() *Token { return &Token{pos, value} } - +// ParseTerm returns nil if no term was found. func (p *parser) parseTerm() (x Expression) { pos := p.pos @@ -95,7 +88,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()} } @@ -119,7 +113,6 @@ func (p *parser) parseTerm() (x Expression) { return x } - func (p *parser) parseSequence() Expression { var list Sequence @@ -130,7 +123,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] } @@ -138,46 +132,42 @@ func (p *parser) parseSequence() Expression { return list } - 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] } return list } - 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} } - 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) @@ -194,7 +184,6 @@ func (p *parser) parse(fset *token.FileSet, filename string, src []byte) Grammar return grammar } - // Parse parses a set of EBNF productions from source src. // It returns a set of productions. Errors are reported // for incorrect syntax and if a production is declared |