aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/ebnf/parser.go
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2011-09-16 15:47:21 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2011-09-16 15:47:21 +0000
commitadb0401dac41c81571722312d4586b2693f95aa6 (patch)
treeea2b52e3c258d6b6d9356977c683c7f72a4a5fd5 /libgo/go/ebnf/parser.go
parent5548ca3540bccbc908a45942896d635ea5f1c23f (diff)
downloadgcc-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.go37
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