Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
G
golang
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
go
golang
Commits
583dac04
Commit
583dac04
authored
Oct 10, 2008
by
Robert Griesemer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
- more cleanups (simpler code for optional semi's, bug fixes)
R=r OCL=16869 CL=16869
parent
bbfe3123
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
73 additions
and
94 deletions
+73
-94
parser.go
usr/gri/pretty/parser.go
+73
-94
No files found.
usr/gri/pretty/parser.go
View file @
583dac04
...
...
@@ -15,10 +15,10 @@ export type Parser struct {
tokchan
*<-
chan
*
Scanner
.
Token
;
// Scanner.Token
old
int
;
// previous token
pos
int
;
// token source position
tok
int
;
// one token look-ahead
val
string
;
// token value (for IDENT, NUMBER, STRING only)
semi
bool
;
// true if a semicolon was inserted by the previous statement
// Nesting level
level
int
;
// 0 = global scope, -1 = function scope of global functions, etc.
...
...
@@ -54,13 +54,13 @@ func (P *Parser) Ecart() {
func
(
P
*
Parser
)
Next
()
{
P
.
old
=
P
.
tok
;
if
P
.
tokchan
==
nil
{
P
.
pos
,
P
.
tok
,
P
.
val
=
P
.
scanner
.
Scan
();
}
else
{
t
:=
<-
P
.
tokchan
;
P
.
tok
,
P
.
pos
,
P
.
val
=
t
.
tok
,
t
.
pos
,
t
.
val
;
}
P
.
semi
=
false
;
if
P
.
verbose
{
P
.
PrintIndent
();
print
(
"["
,
P
.
pos
,
"] "
,
Scanner
.
TokenName
(
P
.
tok
),
"
\n
"
);
...
...
@@ -73,7 +73,6 @@ func (P *Parser) Open(verbose bool, scanner *Scanner.Scanner, tokchan *<-chan *S
P
.
indent
=
0
;
P
.
scanner
=
scanner
;
P
.
tokchan
=
tokchan
;
P
.
old
=
Scanner
.
ILLEGAL
;
P
.
Next
();
P
.
level
=
0
;
}
...
...
@@ -92,8 +91,8 @@ func (P *Parser) Expect(tok int) {
}
func
(
P
*
Parser
)
Opt
ional
(
tok
int
)
{
if
P
.
tok
==
tok
{
func
(
P
*
Parser
)
Opt
Semicolon
(
)
{
if
P
.
tok
==
Scanner
.
SEMICOLON
{
P
.
Next
();
}
}
...
...
@@ -115,22 +114,10 @@ func (P *Parser) CloseScope() {
func
(
P
*
Parser
)
TryType
()
(
typ
AST
.
Type
,
ok
bool
);
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
)
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
{
P
.
Trace
(
"Ident"
);
...
...
@@ -454,7 +441,7 @@ func (P *Parser) ParseStructType() *AST.StructType {
P
.
Expect
(
Scanner
.
SEMICOLON
);
}
}
P
.
Opt
ional
(
Scanner
.
SEMICOLON
);
P
.
Opt
Semicolon
(
);
P
.
Expect
(
Scanner
.
RBRACE
);
}
...
...
@@ -503,31 +490,16 @@ func (P *Parser) TryType() (typ_ AST.Type, ok_ bool) {
// ----------------------------------------------------------------------------
// 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
{
P
.
Trace
(
"StatementList"
);
stats
:=
AST
.
NewList
();
for
{
stat
,
ok
:=
P
.
TryStatement
();
if
ok
{
stats
.
Add
(
stat
);
P
.
Optional
(
Scanner
.
SEMICOLON
);
for
P
.
tok
!=
Scanner
.
CASE
&&
P
.
tok
!=
Scanner
.
DEFAULT
&&
P
.
tok
!=
Scanner
.
RBRACE
&&
P
.
tok
!=
Scanner
.
EOF
{
stats
.
Add
(
P
.
ParseStatement
());
if
P
.
tok
==
Scanner
.
SEMICOLON
{
P
.
Next
();
}
else
if
P
.
semi
{
P
.
semi
=
false
;
// consume inserted ";"
}
else
{
break
;
}
...
...
@@ -546,13 +518,13 @@ func (P *Parser) ParseBlock() *AST.Block {
P
.
Expect
(
Scanner
.
LBRACE
);
P
.
OpenScope
();
if
P
.
tok
!=
Scanner
.
RBRACE
&&
P
.
tok
!=
Scanner
.
SEMICOLON
{
if
P
.
tok
!=
Scanner
.
RBRACE
{
block
.
stats
=
P
.
ParseStatementList
();
}
P
.
Opt
ional
(
Scanner
.
SEMICOLON
);
P
.
Opt
Semicolon
(
);
P
.
CloseScope
();
P
.
Expect
(
Scanner
.
RBRACE
);
P
.
semi
=
true
;
// allow optional semicolon
P
.
Ecart
();
return
block
;
...
...
@@ -801,14 +773,15 @@ func (P *Parser) ParsePrimaryExpr() AST.Expr {
P
.
Trace
(
"PrimaryExpr"
);
x
:=
P
.
ParseOperand
();
L
:
for
{
for
{
switch
P
.
tok
{
case
Scanner
.
PERIOD
:
x
=
P
.
ParseSelectorOrTypeGuard
(
x
);
case
Scanner
.
LBRACK
:
x
=
P
.
ParseIndexOrSlice
(
x
);
case
Scanner
.
LPAREN
:
x
=
P
.
ParseCall
(
x
);
default
:
break
L
;
default
:
goto
exit
;
}
}
exit
:
P
.
Ecart
();
return
x
;
...
...
@@ -899,6 +872,7 @@ func (P *Parser) ParseSimpleStat() AST.Stat {
l
.
ident
=
AST
.
NIL
;
}
P
.
Next
();
// consume ":"
P
.
semi
=
true
;
// allow optional semicolon
stat
=
l
;
case
...
...
@@ -1083,14 +1057,8 @@ func (P *Parser) ParseCaseClause() *AST.CaseClause {
P
.
Trace
(
"CaseClause"
);
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
();
P
.
Optional
(
Scanner
.
SEMICOLON
);
}
if
P
.
tok
==
Scanner
.
FALLTHROUGH
{
P
.
Next
();
clause
.
falls
=
true
;
P
.
Optional
(
Scanner
.
SEMICOLON
);
}
P
.
Ecart
();
...
...
@@ -1107,10 +1075,11 @@ func (P *Parser) ParseSwitchStat() *AST.SwitchStat {
stat
.
cases
=
AST
.
NewList
();
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
());
}
P
.
Expect
(
Scanner
.
RBRACE
);
P
.
semi
=
true
;
// allow optional semicolon
P
.
Ecart
();
return
stat
;
...
...
@@ -1121,20 +1090,11 @@ func (P *Parser) ParseCommCase() {
P
.
Trace
(
"CommCase"
);
if
P
.
tok
==
Scanner
.
CASE
{
P
.
Next
();
if
P
.
tok
==
Scanner
.
GTR
{
// send
P
.
Next
();
P
.
ParseExpression
();
P
.
Expect
(
Scanner
.
EQL
);
P
.
ParseExpression
();
}
else
{
// receive
if
P
.
tok
!=
Scanner
.
LSS
{
P
.
ParseIdent
();
P
.
Expect
(
Scanner
.
ASSIGN
);
}
P
.
Expect
(
Scanner
.
LSS
);
if
P
.
tok
==
Scanner
.
ASSIGN
||
P
.
tok
==
Scanner
.
DEFINE
{
P
.
Next
();
P
.
Expect
(
Scanner
.
ARROW
);
P
.
ParseExpression
();
}
}
else
{
...
...
@@ -1152,26 +1112,12 @@ func (P *Parser) ParseCommClause() {
P
.
ParseCommCase
();
if
P
.
tok
!=
Scanner
.
CASE
&&
P
.
tok
!=
Scanner
.
DEFAULT
&&
P
.
tok
!=
Scanner
.
RBRACE
{
P
.
ParseStatementList
();
P
.
Optional
(
Scanner
.
SEMICOLON
);
}
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
()
{
P
.
Trace
(
"SelectStat"
);
...
...
@@ -1180,18 +1126,46 @@ func (P *Parser) ParseSelectStat() {
for
P
.
tok
!=
Scanner
.
RBRACE
&&
P
.
tok
!=
Scanner
.
EOF
{
P
.
ParseCommClause
();
}
P
.
Next
();
P
.
Expect
(
Scanner
.
RBRACE
);
P
.
semi
=
true
;
// allow optional semicolon
P
.
Ecart
();
}
func
(
P
*
Parser
)
ParseFallthroughStat
()
{
P
.
Trace
(
"FallthroughStat"
);
P
.
Expect
(
Scanner
.
FALLTHROUGH
);
P
.
Ecart
();
}
func
(
P
*
Parser
)
TryStatement
()
(
stat_
AST
.
Stat
,
ok_
bool
)
{
P
.
Trace
(
"Statement (try)"
);
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
;
var
stat
AST
.
Stat
=
AST
.
NIL
;
res
:=
true
;
switch
P
.
tok
{
case
Scanner
.
CONST
,
Scanner
.
TYPE
,
Scanner
.
VAR
:
stat
=
P
.
ParseDeclaration
();
...
...
@@ -1218,16 +1192,17 @@ func (P *Parser) TryStatement() (stat_ AST.Stat, ok_ bool) {
P
.
ParseRangeStat
();
case
Scanner
.
SELECT
:
P
.
ParseSelectStat
();
case
Scanner
.
FALLTHROUGH
:
P
.
ParseFallthroughStat
();
default
:
// no statement found
res
=
false
;
P
.
ParseEmptyStat
();
// for complete tracing output only
}
if
indent
!=
P
.
indent
{
panic
(
"imbalanced tracing code (Statement)"
);
}
P
.
Ecart
();
return
stat
,
res
;
return
stat
;
}
...
...
@@ -1284,6 +1259,7 @@ func (P *Parser) ParseTypeSpec(exported bool) *AST.TypeDecl {
decl
:=
new
(
AST
.
TypeDecl
);
decl
.
ident
=
P
.
ParseIdent
();
decl
.
typ
=
P
.
ParseType
();
P
.
semi
=
true
;
// allow optional semicolon
P
.
Ecart
();
return
decl
;
...
...
@@ -1335,13 +1311,17 @@ func (P *Parser) ParseDecl(exported bool, keyword int) *AST.Declaration {
P
.
Expect
(
keyword
);
if
P
.
tok
==
Scanner
.
LPAREN
{
P
.
Next
();
for
P
.
tok
!=
Scanner
.
RPAREN
&&
P
.
tok
!=
Scanner
.
EOF
{
decl
.
decls
.
Add
(
P
.
ParseSpec
(
exported
,
keyword
));
P
.
OptSemicolon
(
Scanner
.
RPAREN
);
for
P
.
tok
!=
Scanner
.
RPAREN
{
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
{
decl
.
decls
.
Add
(
P
.
ParseSpec
(
exported
,
keyword
));
}
...
...
@@ -1462,8 +1442,6 @@ func (P *Parser) ParseDeclaration() AST.Node {
}
}
P
.
OptSemicolon
(
Scanner
.
RBRACE
);
if
indent
!=
P
.
indent
{
panic
(
"imbalanced tracing code (Declaration)"
);
}
...
...
@@ -1491,11 +1469,12 @@ func (P *Parser) ParseProgram() *AST.Program {
for
P
.
tok
==
Scanner
.
IMPORT
{
decls
.
Add
(
P
.
ParseDecl
(
false
,
Scanner
.
IMPORT
));
P
.
Opt
ional
(
Scanner
.
SEMICOLON
);
P
.
Opt
Semicolon
(
);
}
for
P
.
tok
!=
Scanner
.
EOF
{
decls
.
Add
(
P
.
ParseDeclaration
());
P
.
OptSemicolon
();
}
if
P
.
level
!=
0
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment