Skip to content

Commit c2c5db0

Browse files
committed
ast.Pos updates, and make initial parse work
1 parent f76b12f commit c2c5db0

File tree

4 files changed

+42
-28
lines changed

4 files changed

+42
-28
lines changed

ast/ast.go

+6-6
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ type Singleton py.Object
2525
// All node types implement the Ast interface
2626
type Ast interface {
2727
py.Object
28-
Lineno() int
29-
ColOffset() int
28+
GetLineno() int
29+
GetColOffset() int
3030
}
3131

3232
// All ModBase nodes implement the Mod interface
@@ -55,12 +55,12 @@ type Slicer interface {
5555

5656
// Position in the parse tree
5757
type Pos struct {
58-
lineno int
59-
colOffset int
58+
Lineno int
59+
ColOffset int
6060
}
6161

62-
func (o *Pos) Lineno() int { return o.lineno }
63-
func (o *Pos) ColOffset() int { return o.colOffset }
62+
func (o *Pos) GetLineno() int { return o.Lineno }
63+
func (o *Pos) GetColOffset() int { return o.ColOffset }
6464

6565
// Base AST node
6666
type AST struct {

ast/dump.go

+4
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,11 @@ func Dump(ast Ast) string {
2828
if element.CanInterface() {
2929
if x, ok := element.Interface().(Ast); ok {
3030
strs[i] = Dump(x)
31+
} else {
32+
strs[i] = fmt.Sprintf("%v", element)
3133
}
34+
} else {
35+
strs[i] = fmt.Sprintf("%v", element)
3236
}
3337
}
3438
args = append(args, fmt.Sprintf("%s=[%s]", fname, strings.Join(strs, ",")))

parser/grammar.y

+25-22
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,25 @@ import (
1212
%}
1313

1414
%union {
15-
str string
16-
obj py.Object
17-
ast ast.Ast
18-
mod ast.Mod
19-
stmt ast.Stmt
20-
stmts []ast.Stmt
15+
str string
16+
obj py.Object
17+
ast ast.Ast
18+
mod ast.Mod
19+
stmt ast.Stmt
20+
stmts []ast.Stmt
21+
stmts1 []ast.Stmt // nl_or_stmt accumulator
22+
stmts2 []ast.Stmt // small_stmts accumulator
23+
stmts3 []ast.Stmt // stmts accumulator
24+
pos ast.Pos // kept up to date by the lexer
2125
}
2226

2327
%type <str> strings
2428
%type <ast> atom
2529
%type <mod> inputs file_input
26-
%type <stmts> nl_or_stmt small_stmts simple_stmt stmt stmts
30+
%type <stmts> simple_stmt stmt
31+
%type <stmts1> nl_or_stmt
32+
%type <stmts2> small_stmts
33+
%type <stmts3> stmts
2734
%type <stmt> compound_stmt small_stmt
2835

2936
%token NEWLINE
@@ -132,7 +139,6 @@ nl_or_stmt:
132139
}
133140
| nl_or_stmt NEWLINE
134141
{
135-
$$ = $1
136142
}
137143
| nl_or_stmt stmt
138144
{
@@ -143,7 +149,7 @@ nl_or_stmt:
143149
file_input:
144150
nl_or_stmt ENDMARKER
145151
{
146-
$$ = &ast.Module{Body: $1}
152+
$$ = &ast.Module{ModBase: ast.ModBase{$<pos>$}, Body: $1}
147153
}
148154

149155
// NEWLINE*
@@ -212,19 +218,19 @@ vfpdef: NAME
212218
stmt:
213219
simple_stmt
214220
{
215-
$$ = append($$, $1...)
221+
$$ = $1
216222
}
217223
| compound_stmt
218224
{
219-
$$ = append($$, $1)
225+
$$ = []ast.Stmt{$1}
220226
}
221227

222228
optional_semicolon: | ';'
223229

224230
small_stmts:
225231
small_stmt
226232
{
227-
$$ = append($$, $1)
233+
$$ = []ast.Stmt{$1}
228234
}
229235
| small_stmts ';' small_stmt
230236
{
@@ -246,7 +252,7 @@ small_stmt:
246252
}
247253
| pass_stmt
248254
{
249-
$$ = &ast.Pass{}
255+
$$ = &ast.Pass{StmtBase: ast.StmtBase{$<pos>$}}
250256
}
251257
| flow_stmt
252258
{
@@ -391,7 +397,8 @@ except_clause: EXCEPT | EXCEPT test | EXCEPT test AS NAME
391397
stmts:
392398
stmt
393399
{
394-
$$ = append($$, $1...)
400+
$$ = make([]ast.Stmt, len($1))
401+
copy($$, $1)
395402
}
396403
| stmts stmt
397404
{
@@ -450,8 +457,7 @@ strings:
450457
atom:
451458
'(' ')'
452459
{
453-
// FIXME need lexer to provide ExprBase
454-
$$ = &ast.Tuple{}
460+
$$ = &ast.Tuple{ExprBase: ast.ExprBase{$<pos>$}}
455461
}
456462
| '(' yield_expr ')'
457463
{
@@ -465,8 +471,7 @@ atom:
465471
}
466472
| '[' ']'
467473
{
468-
// FIXME need lexer to provide ExprBase
469-
$$ = &ast.List{}
474+
$$ = &ast.List{ExprBase: ast.ExprBase{$<pos>$}}
470475
}
471476
| '[' testlist_comp ']'
472477
{
@@ -475,8 +480,7 @@ atom:
475480
}
476481
| '{' '}'
477482
{
478-
// FIXME need lexer to provide ExprBase
479-
$$ = &ast.Dict{}
483+
$$ = &ast.Dict{ExprBase: ast.ExprBase{$<pos>$}}
480484
}
481485
| '{' dictorsetmaker '}'
482486
{
@@ -485,8 +489,7 @@ atom:
485489
}
486490
| NAME
487491
{
488-
// FIXME need lexer to provide ExprBase
489-
$$ = &ast.Name{Id: ast.Identifier($1)}
492+
$$ = &ast.Name{ExprBase: ast.ExprBase{$<pos>$}, Id: ast.Identifier($1)}
490493
}
491494
| NUMBER
492495
{

parser/lexer.go

+7
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ const tabSize = 8
3434
type yyLex struct {
3535
reader *bufio.Reader
3636
line string // current line being parsed
37+
pos ast.Pos // position within file
3738
eof bool // flag to show EOF was read
3839
error bool // set if an error has ocurred
3940
errorString string // the string of the error
@@ -308,6 +309,9 @@ func (x *yyLex) Lex(yylval *yySymType) (ret int) {
308309
defer func() { fmt.Printf("LEX> %v\n", newLexToken(ret, yylval)) }()
309310
}
310311

312+
// FIXME keep x.pos up to date
313+
x.pos.Lineno = 42
314+
x.pos.ColOffset = 43
311315
for {
312316
switch x.state {
313317
case readString:
@@ -393,6 +397,9 @@ func (x *yyLex) Lex(yylval *yySymType) (ret int) {
393397
continue
394398
}
395399

400+
// Note start of token for parser
401+
yylval.pos = x.pos
402+
396403
// Read a number if available
397404
token, value := x.readNumber()
398405
if token != eof {

0 commit comments

Comments
 (0)