Commit 583dac04 authored by Robert Griesemer's avatar Robert Griesemer

- more cleanups (simpler code for optional semi's, bug fixes)

R=r
OCL=16869
CL=16869
parent bbfe3123
...@@ -15,10 +15,10 @@ export type Parser struct { ...@@ -15,10 +15,10 @@ 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)
semi bool; // true if a semicolon was inserted by the previous statement
// Nesting level // Nesting level
level int; // 0 = global scope, -1 = function scope of global functions, etc. level int; // 0 = global scope, -1 = function scope of global functions, etc.
...@@ -54,13 +54,13 @@ func (P *Parser) Ecart() { ...@@ -54,13 +54,13 @@ 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 {
t := <-P.tokchan; t := <-P.tokchan;
P.tok, P.pos, P.val = t.tok, t.pos, t.val; P.tok, P.pos, P.val = t.tok, t.pos, t.val;
} }
P.semi = false;
if P.verbose { if P.verbose {
P.PrintIndent(); P.PrintIndent();
print("[", P.pos, "] ", Scanner.TokenName(P.tok), "\n"); print("[", P.pos, "] ", Scanner.TokenName(P.tok), "\n");
...@@ -73,7 +73,6 @@ func (P *Parser) Open(verbose bool, scanner *Scanner.Scanner, tokchan *<-chan *S ...@@ -73,7 +73,6 @@ 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;
} }
...@@ -92,8 +91,8 @@ func (P *Parser) Expect(tok int) { ...@@ -92,8 +91,8 @@ func (P *Parser) Expect(tok int) {
} }
func (P *Parser) Optional(tok int) { func (P *Parser) OptSemicolon() {
if P.tok == tok { if P.tok == Scanner.SEMICOLON {
P.Next(); P.Next();
} }
} }
...@@ -115,22 +114,10 @@ func (P *Parser) CloseScope() { ...@@ -115,22 +114,10 @@ func (P *Parser) CloseScope() {
func (P *Parser) TryType() (typ AST.Type, ok bool); func (P *Parser) TryType() (typ AST.Type, ok bool);
func (P *Parser) ParseExpression() AST.Expr; func (P *Parser) ParseExpression() AST.Expr;
func (P *Parser) TryStatement() (stat AST.Stat, ok bool); func (P *Parser) ParseStatement() AST.Stat;
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");
...@@ -454,7 +441,7 @@ func (P *Parser) ParseStructType() *AST.StructType { ...@@ -454,7 +441,7 @@ func (P *Parser) ParseStructType() *AST.StructType {
P.Expect(Scanner.SEMICOLON); P.Expect(Scanner.SEMICOLON);
} }
} }
P.Optional(Scanner.SEMICOLON); P.OptSemicolon();
P.Expect(Scanner.RBRACE); P.Expect(Scanner.RBRACE);
} }
...@@ -503,31 +490,16 @@ func (P *Parser) TryType() (typ_ AST.Type, ok_ bool) { ...@@ -503,31 +490,16 @@ func (P *Parser) TryType() (typ_ AST.Type, ok_ bool) {
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Blocks // Blocks
func (P *Parser) ParseStatement() AST.Stat {
P.Trace("Statement");
stat, ok := P.TryStatement();
if ok {
P.OptSemicolon(Scanner.RBRACE);
} else {
P.Error(P.pos, "statement expected");
P.Next(); // make progress
}
P.Ecart();
return stat;
}
func (P *Parser) ParseStatementList() *AST.List { func (P *Parser) ParseStatementList() *AST.List {
P.Trace("StatementList"); P.Trace("StatementList");
stats := AST.NewList(); stats := AST.NewList();
for { for P.tok != Scanner.CASE && P.tok != Scanner.DEFAULT && P.tok != Scanner.RBRACE && P.tok != Scanner.EOF {
stat, ok := P.TryStatement(); stats.Add(P.ParseStatement());
if ok { if P.tok == Scanner.SEMICOLON {
stats.Add(stat); P.Next();
P.Optional(Scanner.SEMICOLON); } else if P.semi {
P.semi = false; // consume inserted ";"
} else { } else {
break; break;
} }
...@@ -546,13 +518,13 @@ func (P *Parser) ParseBlock() *AST.Block { ...@@ -546,13 +518,13 @@ func (P *Parser) ParseBlock() *AST.Block {
P.Expect(Scanner.LBRACE); P.Expect(Scanner.LBRACE);
P.OpenScope(); P.OpenScope();
if P.tok != Scanner.RBRACE {
if P.tok != Scanner.RBRACE && P.tok != Scanner.SEMICOLON {
block.stats = P.ParseStatementList(); block.stats = P.ParseStatementList();
} }
P.Optional(Scanner.SEMICOLON); P.OptSemicolon();
P.CloseScope(); P.CloseScope();
P.Expect(Scanner.RBRACE); P.Expect(Scanner.RBRACE);
P.semi = true; // allow optional semicolon
P.Ecart(); P.Ecart();
return block; return block;
...@@ -801,14 +773,15 @@ func (P *Parser) ParsePrimaryExpr() AST.Expr { ...@@ -801,14 +773,15 @@ func (P *Parser) ParsePrimaryExpr() AST.Expr {
P.Trace("PrimaryExpr"); P.Trace("PrimaryExpr");
x := P.ParseOperand(); x := P.ParseOperand();
L: for { for {
switch P.tok { switch P.tok {
case Scanner.PERIOD: x = P.ParseSelectorOrTypeGuard(x); case Scanner.PERIOD: x = P.ParseSelectorOrTypeGuard(x);
case Scanner.LBRACK: x = P.ParseIndexOrSlice(x); case Scanner.LBRACK: x = P.ParseIndexOrSlice(x);
case Scanner.LPAREN: x = P.ParseCall(x); case Scanner.LPAREN: x = P.ParseCall(x);
default: break L; default: goto exit;
} }
} }
exit:
P.Ecart(); P.Ecart();
return x; return x;
...@@ -899,6 +872,7 @@ func (P *Parser) ParseSimpleStat() AST.Stat { ...@@ -899,6 +872,7 @@ func (P *Parser) ParseSimpleStat() AST.Stat {
l.ident = AST.NIL; l.ident = AST.NIL;
} }
P.Next(); // consume ":" P.Next(); // consume ":"
P.semi = true; // allow optional semicolon
stat = l; stat = l;
case case
...@@ -1083,14 +1057,8 @@ func (P *Parser) ParseCaseClause() *AST.CaseClause { ...@@ -1083,14 +1057,8 @@ func (P *Parser) ParseCaseClause() *AST.CaseClause {
P.Trace("CaseClause"); P.Trace("CaseClause");
clause := P.ParseCase(); clause := P.ParseCase();
if P.tok != Scanner.FALLTHROUGH && P.tok != Scanner.RBRACE { if P.tok != Scanner.CASE && P.tok != Scanner.DEFAULT && P.tok != Scanner.RBRACE {
clause.stats = P.ParseStatementList(); clause.stats = P.ParseStatementList();
P.Optional(Scanner.SEMICOLON);
}
if P.tok == Scanner.FALLTHROUGH {
P.Next();
clause.falls = true;
P.Optional(Scanner.SEMICOLON);
} }
P.Ecart(); P.Ecart();
...@@ -1107,10 +1075,11 @@ func (P *Parser) ParseSwitchStat() *AST.SwitchStat { ...@@ -1107,10 +1075,11 @@ func (P *Parser) ParseSwitchStat() *AST.SwitchStat {
stat.cases = AST.NewList(); stat.cases = AST.NewList();
P.Expect(Scanner.LBRACE); P.Expect(Scanner.LBRACE);
for P.tok == Scanner.CASE || P.tok == Scanner.DEFAULT { for P.tok != Scanner.RBRACE && P.tok != Scanner.EOF {
stat.cases.Add(P.ParseCaseClause()); stat.cases.Add(P.ParseCaseClause());
} }
P.Expect(Scanner.RBRACE); P.Expect(Scanner.RBRACE);
P.semi = true; // allow optional semicolon
P.Ecart(); P.Ecart();
return stat; return stat;
...@@ -1122,19 +1091,10 @@ func (P *Parser) ParseCommCase() { ...@@ -1122,19 +1091,10 @@ func (P *Parser) ParseCommCase() {
if P.tok == Scanner.CASE { if P.tok == Scanner.CASE {
P.Next(); P.Next();
if P.tok == Scanner.GTR { P.ParseExpression();
// send if P.tok == Scanner.ASSIGN || P.tok == Scanner.DEFINE {
P.Next(); P.Next();
P.ParseExpression(); P.Expect(Scanner.ARROW);
P.Expect(Scanner.EQL);
P.ParseExpression();
} else {
// receive
if P.tok != Scanner.LSS {
P.ParseIdent();
P.Expect(Scanner.ASSIGN);
}
P.Expect(Scanner.LSS);
P.ParseExpression(); P.ParseExpression();
} }
} else { } else {
...@@ -1152,26 +1112,12 @@ func (P *Parser) ParseCommClause() { ...@@ -1152,26 +1112,12 @@ func (P *Parser) ParseCommClause() {
P.ParseCommCase(); P.ParseCommCase();
if P.tok != Scanner.CASE && P.tok != Scanner.DEFAULT && P.tok != Scanner.RBRACE { if P.tok != Scanner.CASE && P.tok != Scanner.DEFAULT && P.tok != Scanner.RBRACE {
P.ParseStatementList(); P.ParseStatementList();
P.Optional(Scanner.SEMICOLON);
} }
P.Ecart(); P.Ecart();
} }
func (P *Parser) ParseRangeStat() {
P.Trace("RangeStat");
P.Expect(Scanner.RANGE);
P.ParseIdentList();
P.Expect(Scanner.DEFINE);
P.ParseExpression();
P.ParseBlock();
P.Ecart();
}
func (P *Parser) ParseSelectStat() { func (P *Parser) ParseSelectStat() {
P.Trace("SelectStat"); P.Trace("SelectStat");
...@@ -1180,18 +1126,46 @@ func (P *Parser) ParseSelectStat() { ...@@ -1180,18 +1126,46 @@ func (P *Parser) ParseSelectStat() {
for P.tok != Scanner.RBRACE && P.tok != Scanner.EOF { for P.tok != Scanner.RBRACE && P.tok != Scanner.EOF {
P.ParseCommClause(); P.ParseCommClause();
} }
P.Next(); P.Expect(Scanner.RBRACE);
P.semi = true; // allow optional semicolon
P.Ecart(); P.Ecart();
} }
func (P *Parser) TryStatement() (stat_ AST.Stat, ok_ bool) { func (P *Parser) ParseFallthroughStat() {
P.Trace("Statement (try)"); P.Trace("FallthroughStat");
P.Expect(Scanner.FALLTHROUGH);
P.Ecart();
}
func (P *Parser) ParseEmptyStat() {
P.Trace("EmptyStat");
P.Ecart();
}
func (P *Parser) ParseRangeStat() {
P.Trace("RangeStat");
P.Expect(Scanner.RANGE);
P.ParseIdentList();
P.Expect(Scanner.DEFINE);
P.ParseExpression();
P.ParseBlock();
P.Ecart();;
}
func (P *Parser) ParseStatement() AST.Stat {
P.Trace("Statement");
indent := P.indent; indent := P.indent;
var stat AST.Stat = AST.NIL; var stat AST.Stat = AST.NIL;
res := true;
switch P.tok { switch P.tok {
case Scanner.CONST, Scanner.TYPE, Scanner.VAR: case Scanner.CONST, Scanner.TYPE, Scanner.VAR:
stat = P.ParseDeclaration(); stat = P.ParseDeclaration();
...@@ -1218,16 +1192,17 @@ func (P *Parser) TryStatement() (stat_ AST.Stat, ok_ bool) { ...@@ -1218,16 +1192,17 @@ func (P *Parser) TryStatement() (stat_ AST.Stat, ok_ bool) {
P.ParseRangeStat(); P.ParseRangeStat();
case Scanner.SELECT: case Scanner.SELECT:
P.ParseSelectStat(); P.ParseSelectStat();
case Scanner.FALLTHROUGH:
P.ParseFallthroughStat();
default: default:
// no statement found P.ParseEmptyStat(); // for complete tracing output only
res = false;
} }
if indent != P.indent { if indent != P.indent {
panic("imbalanced tracing code (Statement)"); panic("imbalanced tracing code (Statement)");
} }
P.Ecart(); P.Ecart();
return stat, res; return stat;
} }
...@@ -1284,6 +1259,7 @@ func (P *Parser) ParseTypeSpec(exported bool) *AST.TypeDecl { ...@@ -1284,6 +1259,7 @@ func (P *Parser) ParseTypeSpec(exported bool) *AST.TypeDecl {
decl := new(AST.TypeDecl); decl := new(AST.TypeDecl);
decl.ident = P.ParseIdent(); decl.ident = P.ParseIdent();
decl.typ = P.ParseType(); decl.typ = P.ParseType();
P.semi = true; // allow optional semicolon
P.Ecart(); P.Ecart();
return decl; return decl;
...@@ -1335,13 +1311,17 @@ func (P *Parser) ParseDecl(exported bool, keyword int) *AST.Declaration { ...@@ -1335,13 +1311,17 @@ func (P *Parser) ParseDecl(exported bool, keyword int) *AST.Declaration {
P.Expect(keyword); P.Expect(keyword);
if P.tok == Scanner.LPAREN { if P.tok == Scanner.LPAREN {
P.Next(); P.Next();
decl.decls.Add(P.ParseSpec(exported, keyword)); for P.tok != Scanner.RPAREN && P.tok != Scanner.EOF {
P.OptSemicolon(Scanner.RPAREN);
for P.tok != Scanner.RPAREN {
decl.decls.Add(P.ParseSpec(exported, keyword)); decl.decls.Add(P.ParseSpec(exported, keyword));
P.OptSemicolon(Scanner.RPAREN); if P.tok == Scanner.SEMICOLON {
P.Next();
} else {
break;
}
} }
P.Next(); // consume ")" P.Expect(Scanner.RPAREN);
P.semi = true; // allow optional semicolon
} else { } else {
decl.decls.Add(P.ParseSpec(exported, keyword)); decl.decls.Add(P.ParseSpec(exported, keyword));
} }
...@@ -1462,8 +1442,6 @@ func (P *Parser) ParseDeclaration() AST.Node { ...@@ -1462,8 +1442,6 @@ 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)");
} }
...@@ -1491,11 +1469,12 @@ func (P *Parser) ParseProgram() *AST.Program { ...@@ -1491,11 +1469,12 @@ func (P *Parser) ParseProgram() *AST.Program {
for P.tok == Scanner.IMPORT { for P.tok == Scanner.IMPORT {
decls.Add(P.ParseDecl(false, Scanner.IMPORT)); decls.Add(P.ParseDecl(false, Scanner.IMPORT));
P.Optional(Scanner.SEMICOLON); P.OptSemicolon();
} }
for P.tok != Scanner.EOF { for P.tok != Scanner.EOF {
decls.Add(P.ParseDeclaration()); decls.Add(P.ParseDeclaration());
P.OptSemicolon();
} }
if P.level != 0 { if P.level != 0 {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment