1
0
mirror of https://github.com/golang/go synced 2024-11-12 07:40:23 -07:00

- 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

View File

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