Skip to content

Commit 12ea25a

Browse files
committed
Make testlist work
1 parent 33659a5 commit 12ea25a

File tree

2 files changed

+60
-20
lines changed

2 files changed

+60
-20
lines changed

parser/grammar.y

+27-20
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@ import (
1717

1818
// FIXME can put code blocks in not just at the end - help with list initialisation
1919

20-
// FIXME testlist should be a single expression according to the grammar
21-
2220
// A stack of []ast.Expr
2321
type exprsStack [][]ast.Expr
2422

@@ -80,6 +78,7 @@ func (es *stmtsStack) Add(stmt ...ast.Stmt) {
8078
exprs []ast.Expr
8179
exprsStack exprsStack
8280
trailers []ast.Expr // list of trailer expressions
81+
comma bool
8382
}
8483

8584
%type <str> strings
@@ -88,11 +87,12 @@ func (es *stmtsStack) Add(stmt ...ast.Stmt) {
8887
%type <stmtsStack> nl_or_stmt small_stmts stmts
8988
%type <stmt> compound_stmt small_stmt expr_stmt del_stmt pass_stmt flow_stmt import_stmt global_stmt nonlocal_stmt assert_stmt break_stmt continue_stmt return_stmt raise_stmt yield_stmt
9089
%type <op> augassign
91-
%type <expr> expr_or_star_expr expr star_expr xor_expr and_expr shift_expr arith_expr term factor power trailer atom test_or_star_expr test not_test lambdef test_nocond lambdef_nocond or_test and_test comparison
92-
%type <exprs> testlist testlist_star_expr yield_expr_or_testlist yield_expr yield_expr_or_testlist_star_expr exprlist
90+
%type <expr> expr_or_star_expr expr star_expr xor_expr and_expr shift_expr arith_expr term factor power trailer atom test_or_star_expr test not_test lambdef test_nocond lambdef_nocond or_test and_test comparison testlist testlist_star_expr yield_expr_or_testlist yield_expr yield_expr_or_testlist_star_expr
91+
%type <exprs> exprlist
9392
%type <exprsStack> expr_or_star_exprs test_or_star_exprs tests
9493
%type <trailers> trailers
9594
%type <cmpop> comp_op
95+
%type <comma> optional_comma
9696

9797
%token NEWLINE
9898
%token ENDMARKER
@@ -239,16 +239,7 @@ nl_or_stmt:
239239
eval_input:
240240
testlist nls ENDMARKER
241241
{
242-
// FIXME testlist should be a single expression
243-
e := &ast.Expression{ModBase: ast.ModBase{$<pos>$}}
244-
$$ = e
245-
if len($1) > 1 {
246-
e.Body = $1[0]
247-
}
248-
if len($1) > 2 {
249-
panic("FIXME eval_input with more than one testlist")
250-
}
251-
242+
$$ = &ast.Expression{ModBase: ast.ModBase{$<pos>$}, Body: $1}
252243
}
253244

254245
// NEWLINE*
@@ -430,8 +421,7 @@ expr_stmt:
430421
}
431422
| testlist_star_expr
432423
{
433-
// FIXME should testlist really be a single Expr?
434-
$$ = &ast.ExprStmt{StmtBase: ast.StmtBase{$<pos>$}, Value: $1[0]}
424+
$$ = &ast.ExprStmt{StmtBase: ast.StmtBase{$<pos>$}, Value: $1}
435425
}
436426

437427
yield_expr_or_testlist:
@@ -483,12 +473,24 @@ test_or_star_expr:
483473
$$ = $1
484474
}
485475

486-
optional_comma: | ','
476+
optional_comma:
477+
{
478+
$$ = false
479+
}
480+
| ','
481+
{
482+
$$ = true
483+
}
487484

488485
testlist_star_expr:
489486
test_or_star_exprs optional_comma
490487
{
491-
$$ = $1.Pop()
488+
elts := $1.Pop()
489+
if $2 || len(elts) > 1 {
490+
$$ = &ast.Tuple{ExprBase: ast.ExprBase{$<pos>$}, Elts: elts} // FIXME Ctx
491+
} else {
492+
$$ = elts[0]
493+
}
492494
}
493495

494496
augassign:
@@ -1057,7 +1059,7 @@ strings:
10571059
atom:
10581060
'(' ')'
10591061
{
1060-
$$ = &ast.Tuple{ExprBase: ast.ExprBase{$<pos>$}}
1062+
$$ = &ast.Tuple{ExprBase: ast.ExprBase{$<pos>$}} // FIXME Ctx
10611063
}
10621064
| '(' yield_expr ')'
10631065
{
@@ -1206,7 +1208,12 @@ exprlist:
12061208
testlist:
12071209
tests optional_comma
12081210
{
1209-
$$ = $1.Pop()
1211+
elts := $1.Pop()
1212+
if $2 || len(elts) > 1 {
1213+
$$ = &ast.Tuple{ExprBase: ast.ExprBase{$<pos>$}, Elts: elts} // FIXME Ctx
1214+
} else {
1215+
$$ = elts[0]
1216+
}
12101217
}
12111218

12121219
// (',' test ':' test)*

parser/grammar_test.go

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package parser
2+
3+
import (
4+
"testing"
5+
6+
"github.com/ncw/gpython/ast"
7+
)
8+
9+
// FIXME test pos is correct
10+
11+
func TestGrammar(t *testing.T) {
12+
for _, test := range []struct {
13+
in string
14+
mode string
15+
out string
16+
}{
17+
{"", "exec", "Module(Body=[])"},
18+
{"pass", "exec", "Module(Body=[Pass()])"},
19+
{"()", "eval", "Expression(Body=Tuple(Elts=[],Ctx=UnknownExprContext(0)))"},
20+
{"()", "exec", "Module(Body=[ExprStmt(Value=Tuple(Elts=[],Ctx=UnknownExprContext(0)))])"},
21+
{"[ ]", "exec", "Module(Body=[ExprStmt(Value=List(Elts=[],Ctx=UnknownExprContext(0)))])"},
22+
} {
23+
Ast, err := ParseString(test.in, test.mode)
24+
if err != nil {
25+
t.Errorf("Parse(%q) returned error: %v", test.in, err)
26+
} else {
27+
out := ast.Dump(Ast)
28+
if out != test.out {
29+
t.Errorf("Parse(%q) expecting %q actual %q", test.in, test.out, out)
30+
}
31+
}
32+
}
33+
}

0 commit comments

Comments
 (0)