1
0
mirror of https://github.com/golang/go synced 2024-09-25 09:20:18 -06:00

- accept new semicolon syntax (at the moment,

the parser accepts a bit more then it should)

R=r
OCL=16694
CL=16694
This commit is contained in:
Robert Griesemer 2008-10-07 17:57:19 -07:00
parent 38c2472609
commit 44dffd92fc

View File

@ -15,12 +15,13 @@ export type Parser struct {
tokchan *<-chan *Scanner.Token; tokchan *<-chan *Scanner.Token;
// Scanner.Token // Scanner.Token
old int; // previous token
pos int; // token source position pos int; // token source position
tok int; // one token look-ahead tok int; // one token look-ahead
val string; // token value (for IDENT, NUMBER, STRING only) val string; // token value (for IDENT, NUMBER, STRING only)
// Nesting level // Nesting level
level int; // 0 = global scope, -1 = function/struct scope of global functions/structs, etc. level int; // 0 = global scope, -1 = function scope of global functions, etc.
}; };
@ -53,6 +54,7 @@ func (P *Parser) Ecart() {
func (P *Parser) Next() { func (P *Parser) Next() {
P.old = P.tok;
if P.tokchan == nil { if P.tokchan == nil {
P.pos, P.tok, P.val = P.scanner.Scan(); P.pos, P.tok, P.val = P.scanner.Scan();
} else { } else {
@ -71,6 +73,7 @@ func (P *Parser) Open(verbose bool, scanner *Scanner.Scanner, tokchan *<-chan *S
P.indent = 0; P.indent = 0;
P.scanner = scanner; P.scanner = scanner;
P.tokchan = tokchan; P.tokchan = tokchan;
P.old = Scanner.ILLEGAL;
P.Next(); P.Next();
P.level = 0; P.level = 0;
} }
@ -116,6 +119,18 @@ func (P *Parser) TryStatement() (stat AST.Stat, ok bool);
func (P *Parser) ParseDeclaration() AST.Node; func (P *Parser) ParseDeclaration() AST.Node;
func (P *Parser) OptSemicolon(tok int) {
P.Trace("OptSemicolon");
if P.tok == Scanner.SEMICOLON {
P.Next();
} else if P.level != 0 || P.old != tok || P.tok != tok {
// TODO FIX THIS
// P.Expect(Scanner.SEMICOLON);
}
P.Ecart();
}
func (P *Parser) ParseIdent() *AST.Ident { func (P *Parser) ParseIdent() *AST.Ident {
P.Trace("Ident"); P.Trace("Ident");
@ -380,7 +395,6 @@ func (P *Parser) ParseMethodDecl() *AST.MethodDecl {
decl := new(AST.MethodDecl); decl := new(AST.MethodDecl);
decl.ident = P.ParseIdent(); decl.ident = P.ParseIdent();
decl.typ = P.ParseFunctionType(); decl.typ = P.ParseFunctionType();
P.Optional(Scanner.SEMICOLON);
P.Ecart(); P.Ecart();
return decl; return decl;
@ -395,16 +409,18 @@ func (P *Parser) ParseInterfaceType() *AST.InterfaceType {
typ.methods = AST.NewList(); typ.methods = AST.NewList();
P.Expect(Scanner.INTERFACE); P.Expect(Scanner.INTERFACE);
P.Expect(Scanner.LBRACE);
P.OpenScope();
P.level--;
for P.tok == Scanner.IDENT {
typ.methods.Add(P.ParseMethodDecl());
}
P.level++;
P.CloseScope();
P.Expect(Scanner.RBRACE);
if P.tok == Scanner.LBRACE {
P.Next();
for P.tok == Scanner.IDENT {
typ.methods.Add(P.ParseMethodDecl());
if P.tok != Scanner.RBRACE {
P.Expect(Scanner.SEMICOLON);
}
}
P.Expect(Scanner.RBRACE);
}
P.Ecart(); P.Ecart();
return typ; return typ;
} }
@ -435,20 +451,19 @@ func (P *Parser) ParseStructType() *AST.StructType {
typ.fields = AST.NewList(); typ.fields = AST.NewList();
P.Expect(Scanner.STRUCT); P.Expect(Scanner.STRUCT);
P.Expect(Scanner.LBRACE);
P.OpenScope();
P.level--;
for P.tok == Scanner.IDENT {
typ.fields.Add(P.ParseVarDeclList());
if P.tok != Scanner.RBRACE {
P.Expect(Scanner.SEMICOLON);
}
}
P.Optional(Scanner.SEMICOLON);
P.level++;
P.CloseScope();
P.Expect(Scanner.RBRACE);
if P.tok == Scanner.LBRACE {
P.Next();
for P.tok == Scanner.IDENT {
typ.fields.Add(P.ParseVarDeclList());
if P.tok != Scanner.RBRACE {
P.Expect(Scanner.SEMICOLON);
}
}
P.Optional(Scanner.SEMICOLON);
P.Expect(Scanner.RBRACE);
}
P.Ecart(); P.Ecart();
return typ; return typ;
} }
@ -498,12 +513,14 @@ func (P *Parser) ParseStatement() AST.Stat {
P.Trace("Statement"); P.Trace("Statement");
stat, ok := P.TryStatement(); stat, ok := P.TryStatement();
if !ok { if ok {
P.OptSemicolon(Scanner.RBRACE);
} else {
P.Error(P.pos, "statement expected"); P.Error(P.pos, "statement expected");
P.Next(); // make progress P.Next(); // make progress
} }
P.Ecart();
P.Ecart();
return stat; return stat;
} }
@ -1326,10 +1343,7 @@ func (P *Parser) ParseDecl(exported bool, keyword int) *AST.Declaration {
P.Next(); P.Next();
for P.tok != Scanner.RPAREN { for P.tok != Scanner.RPAREN {
decl.decls.Add(P.ParseSpec(exported, keyword)); decl.decls.Add(P.ParseSpec(exported, keyword));
if P.tok != Scanner.RPAREN { P.OptSemicolon(Scanner.RPAREN);
// P.Expect(Scanner.SEMICOLON);
P.Optional(Scanner.SEMICOLON); // TODO this seems wrong! (needed for math.go)
}
} }
P.Next(); // consume ")" P.Next(); // consume ")"
} else { } else {
@ -1350,8 +1364,8 @@ func (P *Parser) ParseDecl(exported bool, keyword int) *AST.Declaration {
// func (recv) ident (params) type // func (recv) ident (params) type
// func (recv) ident (params) (results) // func (recv) ident (params) (results)
func (P *Parser) ParseFuncDecl(exported bool) *AST.FuncDecl { func (P *Parser) ParseFunctionDecl(exported bool) *AST.FuncDecl {
P.Trace("FuncDecl"); P.Trace("FunctionDecl");
fun := new(AST.FuncDecl); fun := new(AST.FuncDecl);
fun.pos = P.pos; fun.pos = P.pos;
@ -1380,10 +1394,7 @@ func (P *Parser) ParseFuncDecl(exported bool) *AST.FuncDecl {
P.level++; P.level++;
P.CloseScope(); P.CloseScope();
if P.tok == Scanner.SEMICOLON { if P.tok == Scanner.LBRACE {
// forward declaration
P.Next();
} else {
fun.body = P.ParseBlock(); fun.body = P.ParseBlock();
} }
@ -1437,7 +1448,7 @@ func (P *Parser) ParseDeclaration() AST.Node {
case Scanner.CONST, Scanner.TYPE, Scanner.VAR: case Scanner.CONST, Scanner.TYPE, Scanner.VAR:
node = P.ParseDecl(exported, P.tok); node = P.ParseDecl(exported, P.tok);
case Scanner.FUNC: case Scanner.FUNC:
node = P.ParseFuncDecl(exported); node = P.ParseFunctionDecl(exported);
case Scanner.EXPORT: case Scanner.EXPORT:
if exported { if exported {
P.Error(P.pos, "cannot mark export declaration for export"); P.Error(P.pos, "cannot mark export declaration for export");
@ -1452,7 +1463,9 @@ func (P *Parser) ParseDeclaration() AST.Node {
P.Next(); // make progress P.Next(); // make progress
} }
} }
P.OptSemicolon(Scanner.RBRACE);
if indent != P.indent { if indent != P.indent {
panic("imbalanced tracing code (Declaration)"); panic("imbalanced tracing code (Declaration)");
} }
@ -1471,7 +1484,6 @@ func (P *Parser) ParseProgram() *AST.Program {
pos := P.pos; pos := P.pos;
P.Expect(Scanner.PACKAGE); P.Expect(Scanner.PACKAGE);
ident := P.ParseIdent(); ident := P.ParseIdent();
P.Optional(Scanner.SEMICOLON);
decls := AST.NewList(); decls := AST.NewList();
{ P.OpenScope(); { P.OpenScope();
@ -1486,7 +1498,6 @@ func (P *Parser) ParseProgram() *AST.Program {
for P.tok != Scanner.EOF { for P.tok != Scanner.EOF {
decls.Add(P.ParseDeclaration()); decls.Add(P.ParseDeclaration());
P.Optional(Scanner.SEMICOLON);
} }
if P.level != 0 { if P.level != 0 {