- go parser parses itself
SVN=126408
diff --git a/usr/gri/src/parser.go b/usr/gri/src/parser.go
index e130bfe..333428c 100644
--- a/usr/gri/src/parser.go
+++ b/usr/gri/src/parser.go
@@ -9,34 +9,61 @@
export Parser
type Parser struct {
- verbose bool;
+ verbose, indent int;
S *Scanner.Scanner;
tok int; // one token look-ahead
beg, end int; // token position
-};
-
-
-func (P *Parser) Next() {
- P.tok, P.beg, P.end = P.S.Scan()
+ ident string; // last ident seen
}
-func (P *Parser) Open(S *Scanner.Scanner, verbose bool) {
+func (P *Parser) PrintIndent() {
+ for i := P.indent; i > 0; i-- {
+ print " ";
+ }
+}
+
+
+func (P *Parser) Trace(msg string) {
+ if P.verbose > 0 {
+ P.PrintIndent();
+ print msg, " {\n";
+ P.indent++;
+ }
+}
+
+
+func (P *Parser) Ecart() {
+ if P.verbose > 0 {
+ P.indent--;
+ P.PrintIndent();
+ print "}\n";
+ }
+}
+
+
+func (P *Parser) Next() {
+ P.tok, P.beg, P.end = P.S.Scan();
+ if P.tok == Scanner.IDENT {
+ P.ident = P.S.src[P.beg : P.end];
+ }
+ if P.verbose > 1 {
+ P.PrintIndent();
+ print Scanner.TokenName(P.tok), "\n";
+ }
+}
+
+
+func (P *Parser) Open(S *Scanner.Scanner, verbose int) {
P.verbose = verbose;
+ P.indent = 0;
P.S = S;
P.Next();
}
func (P *Parser) Error(msg string) {
- print "error: ", msg, "\n";
-}
-
-
-func (P *Parser) Trace(msg string) {
- if P.verbose {
- print msg, "\n";
- }
+ panic "error: ", msg, "\n";
}
@@ -53,7 +80,10 @@
func (P *Parser) ParseIdent() {
- P.Trace("Ident");
+ if P.verbose > 0 {
+ P.PrintIndent();
+ print "Ident = \"", P.ident, "\"\n";
+ }
P.Expect(Scanner.IDENT);
}
@@ -65,6 +95,7 @@
P.Next();
P.ParseIdent();
}
+ P.Ecart();
}
@@ -75,12 +106,14 @@
P.Next();
P.ParseIdent();
}
+ P.Ecart();
}
func (P *Parser) ParseTypeName() {
P.Trace("TypeName");
P.ParseQualifiedIdent();
+ P.Ecart();
}
@@ -92,24 +125,28 @@
}
P.Expect(Scanner.RBRACK);
P.ParseType();
+ P.Ecart();
}
func (P *Parser) ParseChannelType() {
P.Trace("ChannelType");
- panic "ChannelType"
+ panic "ChannelType";
+ P.Ecart();
}
func (P *Parser) ParseInterfaceType() {
P.Trace("InterfaceType");
- panic "InterfaceType"
+ panic "InterfaceType";
+ P.Ecart();
}
func (P *Parser) ParseFunctionType() {
P.Trace("FunctionType");
- panic "FunctionType"
+ panic "FunctionType";
+ P.Ecart();
}
@@ -120,6 +157,7 @@
P.ParseType();
P.Expect(Scanner.RBRACK);
P.ParseType();
+ P.Ecart();
}
@@ -127,6 +165,7 @@
P.Trace("FieldDecl");
P.ParseIdentList();
P.ParseType();
+ P.Ecart();
}
@@ -134,17 +173,17 @@
P.Trace("StructType");
P.Expect(Scanner.STRUCT);
P.Expect(Scanner.LBRACE);
- if P.tok != Scanner.RBRACE {
+ for P.tok != Scanner.RBRACE {
P.ParseFieldDecl();
- for P.tok == Scanner.SEMICOLON {
- P.Next();
- P.ParseFieldDecl();
- }
- if P.tok == Scanner.SEMICOLON {
- P.Next();
+ if P.tok != Scanner.RBRACE {
+ P.Expect(Scanner.SEMICOLON);
}
}
+ if P.tok == Scanner.SEMICOLON {
+ P.Next();
+ }
P.Expect(Scanner.RBRACE);
+ P.Ecart();
}
@@ -152,6 +191,7 @@
P.Trace("PointerType");
P.Expect(Scanner.MUL);
P.ParseType();
+ P.Ecart();
}
@@ -177,6 +217,7 @@
default:
P.Error("type expected");
}
+ P.Ecart();
}
@@ -188,6 +229,7 @@
P.Next();
}
P.Expect(Scanner.STRING);
+ P.Ecart();
}
@@ -206,16 +248,18 @@
} else {
P.ParseImportSpec();
}
+ P.Ecart();
}
func (P *Parser) ParseExpressionList() {
- P.Trace("ExpressionList");
+ P.Trace("ExpressionList");
P.ParseExpression();
for P.tok == Scanner.COMMA {
P.Next();
P.ParseExpression();
}
+ P.Ecart();
}
@@ -234,6 +278,7 @@
P.Next();
P.ParseExpression();
}
+ P.Ecart();
}
@@ -252,6 +297,7 @@
} else {
P.ParseConstSpec();
}
+ P.Ecart();
}
@@ -266,6 +312,7 @@
default:
break;
}
+ P.Ecart();
}
@@ -284,6 +331,7 @@
} else {
P.ParseTypeSpec();
}
+ P.Ecart();
}
@@ -300,6 +348,7 @@
P.ParseExpressionList();
}
}
+ P.Ecart();
}
@@ -318,6 +367,7 @@
} else {
P.ParseVarSpec();
}
+ P.Ecart();
}
@@ -325,6 +375,7 @@
P.Trace("ParameterSection");
P.ParseIdentList();
P.ParseType();
+ P.Ecart();
}
@@ -335,6 +386,7 @@
P.Next();
P.ParseParameterSection();
}
+ P.Ecart();
}
@@ -345,6 +397,7 @@
P.ParseParameterList();
}
P.Expect(Scanner.RPAREN);
+ P.Ecart();
}
@@ -356,6 +409,7 @@
} else {
P.ParseType();
}
+ P.Ecart();
}
@@ -386,17 +440,33 @@
default:
break;
}
+ P.Ecart();
}
func (P *Parser) ParseDeclaration();
-func (P *Parser) ParseStatement();
+func (P *Parser) ParseStatement() bool;
+func (P *Parser) ParseStatementList();
func (P *Parser) ParseBlock();
+func (P *Parser) ParsePrimaryExpr();
func (P *Parser) ParsePrimaryExprList() {
P.Trace("PrimaryExprList");
- panic "PrimaryExprList"
+ P.ParsePrimaryExpr();
+ for P.tok == Scanner.COMMA {
+ P.Next();
+ P.ParsePrimaryExpr();
+ }
+ P.Ecart();
+}
+
+
+func (P *Parser) ParseBuiltinStat() {
+ P.Trace("BuiltinStat");
+ P.Expect(Scanner.IDENT);
+ P.ParseExpressionList(); // TODO should be optional
+ P.Ecart();
}
@@ -404,17 +474,67 @@
P.Trace("SimpleStat");
P.ParseExpression();
switch P.tok {
- case Scanner.ASSIGN:
+ case Scanner.ASSIGN: fallthrough;
+ case Scanner.DEFINE:
P.Next();
P.ParseExpression();
case 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");
+ }
+ P.Next();
+ P.ParseExpressionList();
case Scanner.INC:
P.Next();
case Scanner.DEC:
P.Next();
}
+ P.Ecart();
+}
+
+
+func (P *Parser) ParseReturnStat() {
+ P.Trace("ReturnStat");
+ P.Expect(Scanner.RETURN);
+ if P.tok != Scanner.SEMICOLON && P.tok != Scanner.RBRACE {
+ P.ParseExpressionList();
+ }
+ P.Ecart();
+}
+
+
+func (P *Parser) ParseBreakStat() {
+ P.Trace("BreakStat");
+ P.Expect(Scanner.BREAK);
+ if P.tok == Scanner.IDENT {
+ P.ParseIdent();
+ }
+ P.Ecart();
+}
+
+
+func (P *Parser) ParseContinueStat() {
+ P.Trace("ContinueStat");
+ P.Expect(Scanner.CONTINUE);
+ if P.tok == Scanner.IDENT {
+ P.ParseIdent();
+ }
+ P.Ecart();
}
@@ -434,25 +554,99 @@
P.ParseIfStat();
} else {
// TODO should be P.ParseBlock()
- P.ParseStatement();
+ if !P.ParseStatement() {
+ P.Error("statement expected");
+ }
}
}
+ P.Ecart();
}
func (P *Parser) ParseForStat() {
P.Trace("ForStat");
- panic "for stat";
+ P.Expect(Scanner.FOR);
+ if P.tok != Scanner.LBRACE {
+ if P.tok != Scanner.SEMICOLON {
+ P.ParseSimpleStat();
+ }
+ if P.tok == Scanner.SEMICOLON {
+ P.Next();
+ if P.tok != Scanner.SEMICOLON {
+ P.ParseExpression();
+ }
+ P.Expect(Scanner.SEMICOLON);
+ if P.tok != Scanner.LBRACE {
+ P.ParseSimpleStat();
+ }
+ }
+ }
+ P.ParseBlock();
+ P.Ecart();
+}
+
+
+func (P *Parser) ParseCase() {
+ P.Trace("Case");
+ if P.tok == Scanner.CASE {
+ P.Next();
+ P.ParseExpressionList();
+ } else {
+ P.Expect(Scanner.DEFAULT);
+ }
+ P.Expect(Scanner.COLON);
+ P.Ecart();
+}
+
+
+func (P *Parser) ParseCaseList() {
+ P.Trace("CaseList");
+ P.ParseCase();
+ for P.tok == Scanner.CASE || P.tok == Scanner.DEFAULT {
+ P.ParseCase();
+ }
+ P.Ecart();
+}
+
+
+func (P *Parser) ParseCaseClause() {
+ P.Trace("CaseClause");
+ P.ParseCaseList();
+ if P.tok != Scanner.FALLTHROUGH && P.tok != Scanner.RBRACE {
+ P.ParseStatementList();
+ if P.tok == Scanner.SEMICOLON {
+ P.Next();
+ }
+ }
+ if P.tok == Scanner.FALLTHROUGH {
+ P.Next();
+ if P.tok == Scanner.SEMICOLON {
+ P.Next();
+ }
+ }
+ P.Ecart();
}
func (P *Parser) ParseSwitchStat() {
P.Trace("SwitchStat");
- panic "switch stat";
+ P.Expect(Scanner.SWITCH);
+ if P.tok != Scanner.LBRACE {
+ P.ParseSimpleStat();
+ if P.tok == Scanner.SEMICOLON {
+ P.ParseExpression();
+ }
+ }
+ P.Expect(Scanner.LBRACE);
+ for P.tok != Scanner.RBRACE {
+ P.ParseCaseClause();
+ }
+ P.Expect(Scanner.RBRACE);
+ P.Ecart();
}
-func (P *Parser) ParseStatement() {
+func (P *Parser) ParseStatement() bool {
P.Trace("Statement");
switch P.tok {
case Scanner.CONST: fallthrough;
@@ -461,15 +655,20 @@
case Scanner.FUNC:
P.ParseDeclaration();
case Scanner.IDENT:
- P.ParseSimpleStat();
+ switch P.ident {
+ case "print", "panic":
+ P.ParseBuiltinStat();
+ default:
+ P.ParseSimpleStat();
+ }
case Scanner.GO:
panic "go statement";
case Scanner.RETURN:
- panic "return statement";
+ P.ParseReturnStat();
case Scanner.BREAK:
- panic "break statement";
+ P.ParseBreakStat();
case Scanner.CONTINUE:
- panic "continue statement";
+ P.ParseContinueStat();
case Scanner.GOTO:
panic "goto statement";
case Scanner.LBRACE:
@@ -485,18 +684,23 @@
case Scanner.SELECT:
panic "select statement";
default:
- P.Error("statement expected");
+ // no statement found
+ P.Ecart();
+ return false;
}
+ P.Ecart();
+ return true;
}
func (P *Parser) ParseStatementList() {
P.Trace("StatementList");
- P.ParseStatement();
- for P.tok == Scanner.SEMICOLON {
- P.Next();
- P.ParseStatement();
+ for P.ParseStatement() {
+ if P.tok == Scanner.SEMICOLON {
+ P.Next();
+ }
}
+ P.Ecart();
}
@@ -510,6 +714,7 @@
P.Next();
}
P.Expect(Scanner.RBRACE);
+ P.Ecart();
}
@@ -523,12 +728,19 @@
} else {
P.ParseBlock();
}
+ P.Ecart();
}
func (P *Parser) ParseExportDecl() {
P.Trace("ExportDecl");
- P.Next();
+ P.Expect(Scanner.EXPORT);
+ P.ParseIdent();
+ for P.tok == Scanner.COMMA {
+ P.Next();
+ P.ParseIdent();
+ }
+ P.Ecart();
}
@@ -549,27 +761,85 @@
P.Error("declaration expected");
P.Next(); // make progress
}
+ P.Ecart();
+}
+
+
+func (P *Parser) ParseNew() {
+ P.Trace("New");
+ P.Expect(Scanner.NEW);
+ P.Expect(Scanner.LPAREN);
+ P.ParseType();
+ if P.tok == Scanner.COMMA {
+ P.Next();
+ P.ParseExpressionList()
+ }
+ P.Expect(Scanner.RPAREN);
+ P.Ecart();
}
func (P *Parser) ParseOperand() {
P.Trace("Operand");
- P.Next();
+ switch P.tok {
+ case Scanner.IDENT:
+ P.ParseQualifiedIdent();
+ case Scanner.STRING:
+ fallthrough;
+ case Scanner.NUMBER:
+ P.Next();
+ case Scanner.LPAREN:
+ P.Next();
+ P.ParseExpression();
+ P.Expect(Scanner.LPAREN);
+ case Scanner.IOTA: fallthrough;
+ case Scanner.TRUE: fallthrough;
+ case Scanner.FALSE:
+ P.Next();
+ case Scanner.NEW:
+ P.ParseNew();
+ default:
+ panic "unknown operand"
+ }
+ P.Ecart();
}
func (P *Parser) ParseSelectorOrTypeAssertion() {
P.Trace("SelectorOrTypeAssertion");
+ P.Expect(Scanner.PERIOD);
+ if P.tok == Scanner.IDENT {
+ P.ParseIdent();
+ } else {
+ P.Expect(Scanner.LPAREN);
+ P.ParseType();
+ P.Expect(Scanner.RPAREN);
+ }
+ P.Ecart();
}
func (P *Parser) ParseIndexOrSlice() {
P.Trace("IndexOrSlice");
+ P.Expect(Scanner.LBRACK);
+ P.ParseExpression();
+ if P.tok == Scanner.COLON {
+ P.Next();
+ P.ParseExpression();
+ }
+ P.Expect(Scanner.RBRACK);
+ P.Ecart();
}
func (P *Parser) ParseInvocation() {
P.Trace("Invocation");
+ P.Expect(Scanner.LPAREN);
+ if P.tok != Scanner.RPAREN {
+ P.ParseExpressionList();
+ }
+ P.Expect(Scanner.RPAREN);
+ P.Ecart();
}
@@ -585,9 +855,11 @@
case Scanner.LPAREN:
P.ParseInvocation();
default:
+ P.Ecart();
return;
}
}
+ P.Ecart();
}
@@ -602,10 +874,13 @@
case Scanner.GTR: fallthrough;
case Scanner.MUL: fallthrough;
case Scanner.AND:
+ P.Next();
P.ParseUnaryExpr();
+ P.Ecart();
return;
}
P.ParsePrimaryExpr();
+ P.Ecart();
}
@@ -622,9 +897,11 @@
case Scanner.AND:
P.ParseUnaryExpr();
default:
+ P.Ecart();
return;
}
}
+ P.Ecart();
}
@@ -639,9 +916,11 @@
case Scanner.XOR:
P.ParseMultiplicativeExpr();
default:
+ P.Ecart();
return;
}
}
+ P.Ecart();
}
@@ -655,8 +934,10 @@
case Scanner.LEQ: fallthrough;
case Scanner.GTR: fallthrough;
case Scanner.GEQ:
+ P.Next();
P.ParseAdditiveExpr();
}
+ P.Ecart();
}
@@ -667,6 +948,7 @@
P.Next();
P.ParseRelationalExpr();
}
+ P.Ecart();
}
@@ -677,12 +959,14 @@
P.Next();
P.ParseLANDExpr();
}
+ P.Ecart();
}
func (P *Parser) ParseExpression() {
P.Trace("Expression");
- P.Next();
+ P.ParseLORExpr();
+ P.Ecart();
}
@@ -702,4 +986,5 @@
P.Next();
}
}
+ P.Ecart();
}