- more work on Go parser

- added tests

SVN=126439
This commit is contained in:
Robert Griesemer 2008-07-08 18:37:31 -07:00
parent 41b9617be4
commit 8e4ee0045f
1 changed files with 112 additions and 110 deletions

View File

@ -4,6 +4,7 @@
package Parser package Parser
//import . "scanner"
import Scanner "scanner" import Scanner "scanner"
@ -64,18 +65,27 @@ func (P *Parser) Open(S *Scanner.Scanner, verbose int) {
func (P *Parser) Error(msg string) { func (P *Parser) Error(msg string) {
panic "error: ", msg, "\n"; panic "error: ", msg, "\n";
P.Next(); // make progress
} }
func (P *Parser) Expect(tok int) { func (P *Parser) Expect(tok int) {
if tok != P.tok { if P.tok == tok {
P.Next()
} else {
P.Error("expected `" + Scanner.TokenName(tok) + "`, found `" + Scanner.TokenName(P.tok) + "`"); P.Error("expected `" + Scanner.TokenName(tok) + "`, found `" + Scanner.TokenName(P.tok) + "`");
} }
P.Next(); // make progress in any case
} }
func (P *Parser) ParseType(); func (P *Parser) Optional(tok int) {
if P.tok == tok {
P.Next();
}
}
func (P *Parser) TryType() bool;
func (P *Parser) ParseExpression(); func (P *Parser) ParseExpression();
@ -117,6 +127,15 @@ func (P *Parser) ParseTypeName() {
} }
func (P *Parser) ParseType() {
P.Trace("Type");
if !P.TryType() {
P.Error("type expected");
}
P.Ecart();
}
func (P *Parser) ParseArrayType() { func (P *Parser) ParseArrayType() {
P.Trace("ArrayType"); P.Trace("ArrayType");
P.Expect(Scanner.LBRACK); P.Expect(Scanner.LBRACK);
@ -131,7 +150,13 @@ func (P *Parser) ParseArrayType() {
func (P *Parser) ParseChannelType() { func (P *Parser) ParseChannelType() {
P.Trace("ChannelType"); P.Trace("ChannelType");
panic "ChannelType"; P.Expect(Scanner.CHAN);
switch P.tok {
case Scanner.LSS: fallthrough
case Scanner.GTR:
P.Next();
}
P.ParseType();
P.Ecart(); P.Ecart();
} }
@ -179,9 +204,7 @@ func (P *Parser) ParseStructType() {
P.Expect(Scanner.SEMICOLON); P.Expect(Scanner.SEMICOLON);
} }
} }
if P.tok == Scanner.SEMICOLON { P.Optional(Scanner.SEMICOLON);
P.Next();
}
P.Expect(Scanner.RBRACE); P.Expect(Scanner.RBRACE);
P.Ecart(); P.Ecart();
} }
@ -195,8 +218,8 @@ func (P *Parser) ParsePointerType() {
} }
func (P *Parser) ParseType() { func (P *Parser) TryType() bool {
P.Trace("Type"); P.Trace("Type (try)");
switch P.tok { switch P.tok {
case Scanner.IDENT: case Scanner.IDENT:
P.ParseTypeName(); P.ParseTypeName();
@ -215,9 +238,11 @@ func (P *Parser) ParseType() {
case Scanner.MUL: case Scanner.MUL:
P.ParsePointerType(); P.ParsePointerType();
default: default:
P.Error("type expected"); P.Ecart();
return false;
} }
P.Ecart(); P.Ecart();
return true;
} }
@ -242,9 +267,7 @@ func (P *Parser) ParseImportDecl() {
P.Next(); P.Next();
P.ParseImportSpec(); P.ParseImportSpec();
} }
if P.tok == Scanner.SEMICOLON { P.Optional(Scanner.SEMICOLON);
P.Next();
}
} else { } else {
P.ParseImportSpec(); P.ParseImportSpec();
} }
@ -266,14 +289,7 @@ func (P *Parser) ParseExpressionList() {
func (P *Parser) ParseConstSpec() { func (P *Parser) ParseConstSpec() {
P.Trace("ConstSpec"); P.Trace("ConstSpec");
P.ParseIdent(); P.ParseIdent();
// TODO factor this code P.TryType();
switch P.tok {
case Scanner.IDENT, Scanner.LBRACK, Scanner.CHAN, Scanner.INTERFACE,
Scanner.FUNC, Scanner.MAP, Scanner.STRUCT, Scanner.MUL:
P.ParseType();
default:
break;
}
if P.tok == Scanner.ASSIGN { if P.tok == Scanner.ASSIGN {
P.Next(); P.Next();
P.ParseExpression(); P.ParseExpression();
@ -286,14 +302,14 @@ func (P *Parser) ParseConstDecl() {
P.Trace("ConstDecl"); P.Trace("ConstDecl");
P.Expect(Scanner.CONST); P.Expect(Scanner.CONST);
if P.tok == Scanner.LPAREN { if P.tok == Scanner.LPAREN {
P.ParseConstSpec(); P.Next();
for P.tok == Scanner.SEMICOLON { for P.tok != Scanner.RPAREN {
P.Next();
P.ParseConstSpec(); P.ParseConstSpec();
if P.tok != Scanner.RPAREN {
P.Expect(Scanner.SEMICOLON);
}
} }
if P.tok == Scanner.SEMICOLON { P.Next();
P.Next();
}
} else { } else {
P.ParseConstSpec(); P.ParseConstSpec();
} }
@ -304,14 +320,7 @@ func (P *Parser) ParseConstDecl() {
func (P *Parser) ParseTypeSpec() { func (P *Parser) ParseTypeSpec() {
P.Trace("TypeSpec"); P.Trace("TypeSpec");
P.ParseIdent(); P.ParseIdent();
// TODO factor this code P.TryType();
switch P.tok {
case Scanner.IDENT, Scanner.LBRACK, Scanner.CHAN, Scanner.INTERFACE,
Scanner.FUNC, Scanner.MAP, Scanner.STRUCT, Scanner.MUL:
P.ParseType();
default:
break;
}
P.Ecart(); P.Ecart();
} }
@ -320,14 +329,14 @@ func (P *Parser) ParseTypeDecl() {
P.Trace("TypeDecl"); P.Trace("TypeDecl");
P.Expect(Scanner.TYPE); P.Expect(Scanner.TYPE);
if P.tok == Scanner.LPAREN { if P.tok == Scanner.LPAREN {
P.ParseTypeSpec(); P.Next();
for P.tok == Scanner.SEMICOLON { for P.tok != Scanner.RPAREN {
P.Next();
P.ParseTypeSpec(); P.ParseTypeSpec();
if P.tok != Scanner.RPAREN {
P.Expect(Scanner.SEMICOLON);
}
} }
if P.tok == Scanner.SEMICOLON { P.Next();
P.Next();
}
} else { } else {
P.ParseTypeSpec(); P.ParseTypeSpec();
} }
@ -356,14 +365,14 @@ func (P *Parser) ParseVarDecl() {
P.Trace("VarDecl"); P.Trace("VarDecl");
P.Expect(Scanner.VAR); P.Expect(Scanner.VAR);
if P.tok == Scanner.LPAREN { if P.tok == Scanner.LPAREN {
P.ParseVarSpec(); P.Next();
for P.tok == Scanner.SEMICOLON { for P.tok != Scanner.RPAREN {
P.Next();
P.ParseVarSpec(); P.ParseVarSpec();
if P.tok != Scanner.RPAREN {
P.Expect(Scanner.SEMICOLON);
}
} }
if P.tok == Scanner.SEMICOLON { P.Next();
P.Next();
}
} else { } else {
P.ParseVarSpec(); P.ParseVarSpec();
} }
@ -445,7 +454,7 @@ func (P *Parser) ParseNamedSignature() {
func (P *Parser) ParseDeclaration(); func (P *Parser) ParseDeclaration();
func (P *Parser) ParseStatement() bool; func (P *Parser) TryStatement() bool;
func (P *Parser) ParseStatementList(); func (P *Parser) ParseStatementList();
func (P *Parser) ParseBlock(); func (P *Parser) ParseBlock();
func (P *Parser) ParsePrimaryExpr(); func (P *Parser) ParsePrimaryExpr();
@ -473,30 +482,28 @@ func (P *Parser) ParseBuiltinStat() {
func (P *Parser) ParseSimpleStat() { func (P *Parser) ParseSimpleStat() {
P.Trace("SimpleStat"); P.Trace("SimpleStat");
P.ParseExpression(); P.ParseExpression();
switch P.tok { if P.tok == Scanner.COLON {
case Scanner.ASSIGN: fallthrough;
case Scanner.DEFINE:
P.Next(); P.Next();
P.ParseExpression(); P.Ecart();
case Scanner.COMMA: return;
}
if P.tok == Scanner.COMMA {
P.Next(); P.Next();
P.ParsePrimaryExprList(); P.ParsePrimaryExprList();
switch P.tok { }
case Scanner.ASSIGN: switch P.tok {
case Scanner.ADD_ASSIGN: case Scanner.ASSIGN: fallthrough;
case Scanner.SUB_ASSIGN: case Scanner.DEFINE: fallthrough;
case Scanner.MUL_ASSIGN: case Scanner.ADD_ASSIGN: fallthrough;
case Scanner.QUO_ASSIGN: case Scanner.SUB_ASSIGN: fallthrough;
case Scanner.REM_ASSIGN: case Scanner.MUL_ASSIGN: fallthrough;
case Scanner.AND_ASSIGN: case Scanner.QUO_ASSIGN: fallthrough;
case Scanner.OR_ASSIGN: case Scanner.REM_ASSIGN: fallthrough;
case Scanner.XOR_ASSIGN: case Scanner.AND_ASSIGN: fallthrough;
case Scanner.SHL_ASSIGN: case Scanner.OR_ASSIGN: fallthrough;
case Scanner.SHR_ASSIGN: case Scanner.XOR_ASSIGN: fallthrough;
break; case Scanner.SHL_ASSIGN: fallthrough;
default: case Scanner.SHR_ASSIGN:
P.Error("expected assignment operand");
}
P.Next(); P.Next();
P.ParseExpressionList(); P.ParseExpressionList();
case Scanner.INC: case Scanner.INC:
@ -508,6 +515,13 @@ func (P *Parser) ParseSimpleStat() {
} }
func (P *Parser) ParseGoStat() {
P.Trace("GoStat");
P.Expect(Scanner.GO);
P.ParseExpression();
}
func (P *Parser) ParseReturnStat() { func (P *Parser) ParseReturnStat() {
P.Trace("ReturnStat"); P.Trace("ReturnStat");
P.Expect(Scanner.RETURN); P.Expect(Scanner.RETURN);
@ -518,9 +532,9 @@ func (P *Parser) ParseReturnStat() {
} }
func (P *Parser) ParseBreakStat() { func (P *Parser) ParseControlFlowStat(tok int) {
P.Trace("BreakStat"); P.Trace("ControlFlowStat");
P.Expect(Scanner.BREAK); P.Expect(tok);
if P.tok == Scanner.IDENT { if P.tok == Scanner.IDENT {
P.ParseIdent(); P.ParseIdent();
} }
@ -528,11 +542,10 @@ func (P *Parser) ParseBreakStat() {
} }
func (P *Parser) ParseContinueStat() { func (P *Parser) ParseStatement() {
P.Trace("ContinueStat"); P.Trace("Statement");
P.Expect(Scanner.CONTINUE); if !P.TryStatement() {
if P.tok == Scanner.IDENT { P.Error("statement expected");
P.ParseIdent();
} }
P.Ecart(); P.Ecart();
} }
@ -544,6 +557,7 @@ func (P *Parser) ParseIfStat() {
if P.tok != Scanner.LBRACE { if P.tok != Scanner.LBRACE {
P.ParseSimpleStat(); P.ParseSimpleStat();
if P.tok == Scanner.SEMICOLON { if P.tok == Scanner.SEMICOLON {
P.Next();
P.ParseExpression(); P.ParseExpression();
} }
} }
@ -554,9 +568,7 @@ func (P *Parser) ParseIfStat() {
P.ParseIfStat(); P.ParseIfStat();
} else { } else {
// TODO should be P.ParseBlock() // TODO should be P.ParseBlock()
if !P.ParseStatement() { P.ParseStatement();
P.Error("statement expected");
}
} }
} }
P.Ecart(); P.Ecart();
@ -614,15 +626,11 @@ func (P *Parser) ParseCaseClause() {
P.ParseCaseList(); P.ParseCaseList();
if P.tok != Scanner.FALLTHROUGH && P.tok != Scanner.RBRACE { if P.tok != Scanner.FALLTHROUGH && P.tok != Scanner.RBRACE {
P.ParseStatementList(); P.ParseStatementList();
if P.tok == Scanner.SEMICOLON { P.Optional(Scanner.SEMICOLON);
P.Next();
}
} }
if P.tok == Scanner.FALLTHROUGH { if P.tok == Scanner.FALLTHROUGH {
P.Next(); P.Next();
if P.tok == Scanner.SEMICOLON { P.Optional(Scanner.SEMICOLON);
P.Next();
}
} }
P.Ecart(); P.Ecart();
} }
@ -634,6 +642,7 @@ func (P *Parser) ParseSwitchStat() {
if P.tok != Scanner.LBRACE { if P.tok != Scanner.LBRACE {
P.ParseSimpleStat(); P.ParseSimpleStat();
if P.tok == Scanner.SEMICOLON { if P.tok == Scanner.SEMICOLON {
P.Next();
P.ParseExpression(); P.ParseExpression();
} }
} }
@ -646,14 +655,16 @@ func (P *Parser) ParseSwitchStat() {
} }
func (P *Parser) ParseStatement() bool { func (P *Parser) TryStatement() bool {
P.Trace("Statement"); P.Trace("Statement (try)");
switch P.tok { switch P.tok {
case Scanner.CONST: fallthrough; case Scanner.CONST: fallthrough;
case Scanner.TYPE: fallthrough; case Scanner.TYPE: fallthrough;
case Scanner.VAR: fallthrough; case Scanner.VAR: fallthrough;
case Scanner.FUNC: case Scanner.FUNC:
P.ParseDeclaration(); P.ParseDeclaration();
case Scanner.GTR:
P.ParseSimpleStat(); // send
case Scanner.IDENT: case Scanner.IDENT:
switch P.ident { switch P.ident {
case "print", "panic": case "print", "panic":
@ -662,15 +673,11 @@ func (P *Parser) ParseStatement() bool {
P.ParseSimpleStat(); P.ParseSimpleStat();
} }
case Scanner.GO: case Scanner.GO:
panic "go statement"; P.ParseGoStat();
case Scanner.RETURN: case Scanner.RETURN:
P.ParseReturnStat(); P.ParseReturnStat();
case Scanner.BREAK: case Scanner.BREAK, Scanner.CONTINUE, Scanner.GOTO:
P.ParseBreakStat(); P.ParseControlFlowStat(P.tok);
case Scanner.CONTINUE:
P.ParseContinueStat();
case Scanner.GOTO:
panic "goto statement";
case Scanner.LBRACE: case Scanner.LBRACE:
P.ParseBlock(); P.ParseBlock();
case Scanner.IF: case Scanner.IF:
@ -695,10 +702,8 @@ func (P *Parser) ParseStatement() bool {
func (P *Parser) ParseStatementList() { func (P *Parser) ParseStatementList() {
P.Trace("StatementList"); P.Trace("StatementList");
for P.ParseStatement() { for P.TryStatement() {
if P.tok == Scanner.SEMICOLON { P.Optional(Scanner.SEMICOLON);
P.Next();
}
} }
P.Ecart(); P.Ecart();
} }
@ -710,9 +715,7 @@ func (P *Parser) ParseBlock() {
if P.tok != Scanner.RBRACE && P.tok != Scanner.SEMICOLON { if P.tok != Scanner.RBRACE && P.tok != Scanner.SEMICOLON {
P.ParseStatementList(); P.ParseStatementList();
} }
if P.tok == Scanner.SEMICOLON { P.Optional(Scanner.SEMICOLON);
P.Next();
}
P.Expect(Scanner.RBRACE); P.Expect(Scanner.RBRACE);
P.Ecart(); P.Ecart();
} }
@ -740,6 +743,7 @@ func (P *Parser) ParseExportDecl() {
P.Next(); P.Next();
P.ParseIdent(); P.ParseIdent();
} }
P.Optional(Scanner.COMMA);
P.Ecart(); P.Ecart();
} }
@ -759,7 +763,6 @@ func (P *Parser) ParseDeclaration() {
P.ParseExportDecl(); P.ParseExportDecl();
default: default:
P.Error("declaration expected"); P.Error("declaration expected");
P.Next(); // make progress
} }
P.Ecart(); P.Ecart();
} }
@ -791,7 +794,8 @@ func (P *Parser) ParseOperand() {
case Scanner.LPAREN: case Scanner.LPAREN:
P.Next(); P.Next();
P.ParseExpression(); P.ParseExpression();
P.Expect(Scanner.LPAREN); P.Expect(Scanner.RPAREN);
case Scanner.NIL: fallthrough;
case Scanner.IOTA: fallthrough; case Scanner.IOTA: fallthrough;
case Scanner.TRUE: fallthrough; case Scanner.TRUE: fallthrough;
case Scanner.FALSE: case Scanner.FALSE:
@ -895,6 +899,7 @@ func (P *Parser) ParseMultiplicativeExpr() {
case Scanner.SHL: fallthrough; case Scanner.SHL: fallthrough;
case Scanner.SHR: fallthrough; case Scanner.SHR: fallthrough;
case Scanner.AND: case Scanner.AND:
P.Next();
P.ParseUnaryExpr(); P.ParseUnaryExpr();
default: default:
P.Ecart(); P.Ecart();
@ -914,6 +919,7 @@ func (P *Parser) ParseAdditiveExpr() {
case Scanner.SUB: fallthrough; case Scanner.SUB: fallthrough;
case Scanner.OR: fallthrough; case Scanner.OR: fallthrough;
case Scanner.XOR: case Scanner.XOR:
P.Next();
P.ParseMultiplicativeExpr(); P.ParseMultiplicativeExpr();
default: default:
P.Ecart(); P.Ecart();
@ -976,15 +982,11 @@ func (P *Parser) ParseProgram() {
P.ParseIdent(); P.ParseIdent();
for P.tok == Scanner.IMPORT { for P.tok == Scanner.IMPORT {
P.ParseImportDecl(); P.ParseImportDecl();
if P.tok == Scanner.SEMICOLON { P.Optional(Scanner.SEMICOLON);
P.Next();
}
} }
for P.tok != Scanner.EOF { for P.tok != Scanner.EOF {
P.ParseDeclaration(); P.ParseDeclaration();
if P.tok == Scanner.SEMICOLON { P.Optional(Scanner.SEMICOLON);
P.Next();
}
} }
P.Ecart(); P.Ecart();
} }