mirror of
https://github.com/golang/go
synced 2024-11-12 09:30:25 -07: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:
parent
38c2472609
commit
44dffd92fc
@ -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,15 +409,17 @@ 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();
|
if P.tok == Scanner.LBRACE {
|
||||||
P.level--;
|
P.Next();
|
||||||
for P.tok == Scanner.IDENT {
|
for P.tok == Scanner.IDENT {
|
||||||
typ.methods.Add(P.ParseMethodDecl());
|
typ.methods.Add(P.ParseMethodDecl());
|
||||||
|
if P.tok != Scanner.RBRACE {
|
||||||
|
P.Expect(Scanner.SEMICOLON);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
P.Expect(Scanner.RBRACE);
|
||||||
}
|
}
|
||||||
P.level++;
|
|
||||||
P.CloseScope();
|
|
||||||
P.Expect(Scanner.RBRACE);
|
|
||||||
|
|
||||||
P.Ecart();
|
P.Ecart();
|
||||||
return typ;
|
return typ;
|
||||||
@ -435,19 +451,18 @@ 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();
|
if P.tok == Scanner.LBRACE {
|
||||||
P.level--;
|
P.Next();
|
||||||
for P.tok == Scanner.IDENT {
|
for P.tok == Scanner.IDENT {
|
||||||
typ.fields.Add(P.ParseVarDeclList());
|
typ.fields.Add(P.ParseVarDeclList());
|
||||||
if P.tok != Scanner.RBRACE {
|
if P.tok != Scanner.RBRACE {
|
||||||
P.Expect(Scanner.SEMICOLON);
|
P.Expect(Scanner.SEMICOLON);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
P.Optional(Scanner.SEMICOLON);
|
||||||
|
P.Expect(Scanner.RBRACE);
|
||||||
}
|
}
|
||||||
P.Optional(Scanner.SEMICOLON);
|
|
||||||
P.level++;
|
|
||||||
P.CloseScope();
|
|
||||||
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");
|
||||||
@ -1453,6 +1464,8 @@ func (P *Parser) ParseDeclaration() AST.Node {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 {
|
||||||
|
Loading…
Reference in New Issue
Block a user