Skip to content

Commit 034315f

Browse files
committed
try / except statememts
1 parent 79b119d commit 034315f

File tree

5 files changed

+86
-27
lines changed

5 files changed

+86
-27
lines changed

ast/ast.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ type Raise struct {
350350
type Try struct {
351351
StmtBase
352352
Body []Stmt
353-
Handlers []ExceptHandler
353+
Handlers []*ExceptHandler
354354
Orelse []Stmt
355355
Finalbody []Stmt
356356
}
@@ -643,7 +643,7 @@ type Comprehension struct {
643643

644644
type ExceptHandler struct {
645645
Pos
646-
Exprtype Expr
646+
ExprType Expr
647647
Name Identifier
648648
Body []Stmt
649649
}
@@ -673,7 +673,7 @@ type Keyword struct {
673673
type Alias struct {
674674
Pos
675675
Name Identifier
676-
AsName *Identifier
676+
AsName Identifier
677677
}
678678

679679
type WithItem struct {

ast/dump.go

+6-5
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,10 @@ func dumpItem(v interface{}) string {
1818
case py.Bytes:
1919
return fmt.Sprintf("b'%s'", string(x))
2020
case Identifier:
21-
return fmt.Sprintf("'%s'", string(x))
22-
case *Identifier:
23-
if x == nil {
21+
if x == "" {
2422
return "None"
2523
}
26-
return fmt.Sprintf("'%s'", string(*x))
24+
return fmt.Sprintf("'%s'", string(x))
2725
case *Keyword:
2826
return dump(x, "keyword")
2927
case ModBase:
@@ -52,8 +50,11 @@ func dump(ast interface{}, name string) string {
5250
fieldType := astType.Field(i)
5351
fieldValue := astValue.Field(i)
5452
fname := strings.ToLower(fieldType.Name)
55-
if fname == "stmtbase" || fname == "exprbase" || fname == "modbase" || fname == "slicebase" || fname == "pos" {
53+
switch fname {
54+
case "stmtbase", "exprbase", "modbase", "slicebase", "pos":
5655
continue
56+
case "exprtype":
57+
fname = "type"
5758
}
5859
if fieldValue.Kind() == reflect.Slice && fieldValue.Type().Elem().Kind() != reflect.Uint8 {
5960
strs := make([]string, fieldValue.Len())

parser/grammar.y

+23-19
Original file line numberDiff line numberDiff line change
@@ -66,14 +66,15 @@ func applyTrailers(expr ast.Expr, trailers []ast.Expr) ast.Expr {
6666
identifiers []ast.Identifier
6767
ifstmt *ast.If
6868
lastif *ast.If
69+
exchandlers []*ast.ExceptHandler
6970
}
7071

7172
%type <obj> strings
7273
%type <mod> inputs file_input single_input eval_input
7374
%type <stmts> simple_stmt stmt nl_or_stmt small_stmts stmts suite optional_else
74-
%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 import_name import_from while_stmt if_stmt for_stmt
75+
%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 import_name import_from while_stmt if_stmt for_stmt try_stmt with_stmt
7576
%type <op> augassign
76-
%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 dictorsetmaker sliceop arglist
77+
%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 dictorsetmaker sliceop arglist except_clause
7778
%type <exprs> exprlist testlistraw comp_if comp_iter expr_or_star_exprs test_or_star_exprs tests test_colon_tests trailers
7879
%type <cmpop> comp_op
7980
%type <comma> optional_comma
@@ -86,6 +87,7 @@ func applyTrailers(expr ast.Expr, trailers []ast.Expr) ast.Expr {
8687
%type <alias> dotted_as_name import_as_name
8788
%type <aliases> dotted_as_names import_as_names import_from_arg
8889
%type <ifstmt> elifs
90+
%type <exchandlers> except_clauses
8991

9092
%token NEWLINE
9193
%token ENDMARKER
@@ -833,8 +835,7 @@ import_as_name:
833835
}
834836
| NAME AS NAME
835837
{
836-
as := ast.Identifier($3)
837-
$$ = &ast.Alias{Pos: $<pos>$, Name: ast.Identifier($1), AsName: &as}
838+
$$ = &ast.Alias{Pos: $<pos>$, Name: ast.Identifier($1), AsName: ast.Identifier($3)}
838839
}
839840

840841
dotted_as_name:
@@ -844,8 +845,7 @@ dotted_as_name:
844845
}
845846
| dotted_name AS NAME
846847
{
847-
as := ast.Identifier($3)
848-
$$ = &ast.Alias{Pos: $<pos>$, Name: ast.Identifier($1), AsName: &as}
848+
$$ = &ast.Alias{Pos: $<pos>$, Name: ast.Identifier($1), AsName: ast.Identifier($3)}
849849
}
850850

851851
import_as_names:
@@ -927,23 +927,23 @@ assert_stmt:
927927
compound_stmt:
928928
if_stmt
929929
{
930-
// FIXME
930+
$$ = $1
931931
}
932932
| while_stmt
933933
{
934934
$$ = $1
935935
}
936936
| for_stmt
937937
{
938-
// FIXME
938+
$$ = $1
939939
}
940940
| try_stmt
941941
{
942-
// FIXME
942+
$$ = $1
943943
}
944944
| with_stmt
945945
{
946-
// FIXME
946+
$$ = $1
947947
}
948948
| funcdef
949949
{
@@ -1021,29 +1021,30 @@ for_stmt:
10211021

10221022
except_clauses:
10231023
{
1024-
// FIXME
1024+
$$ = nil
10251025
}
10261026
| except_clauses except_clause ':' suite
10271027
{
1028-
// FIXME
1028+
exc := &ast.ExceptHandler{Pos: $<pos>$, ExprType: $2, Name: ast.Identifier($<str>2), Body: $4}
1029+
$$ = append($$, exc)
10291030
}
10301031

10311032
try_stmt:
10321033
TRY ':' suite except_clauses
10331034
{
1034-
// FIXME
1035+
$$ = &ast.Try{StmtBase: ast.StmtBase{$<pos>$}, Body: $3, Handlers: $4}
10351036
}
10361037
| TRY ':' suite except_clauses ELSE ':' suite
10371038
{
1038-
// FIXME
1039+
$$ = &ast.Try{StmtBase: ast.StmtBase{$<pos>$}, Body: $3, Handlers: $4, Orelse: $7}
10391040
}
10401041
| TRY ':' suite except_clauses FINALLY ':' suite
10411042
{
1042-
// FIXME
1043+
$$ = &ast.Try{StmtBase: ast.StmtBase{$<pos>$}, Body: $3, Handlers: $4, Finalbody: $7}
10431044
}
10441045
| TRY ':' suite except_clauses ELSE ':' suite FINALLY ':' suite
10451046
{
1046-
// FIXME
1047+
$$ = &ast.Try{StmtBase: ast.StmtBase{$<pos>$}, Body: $3, Handlers: $4, Orelse: $7, Finalbody: $10}
10471048
}
10481049

10491050
with_items:
@@ -1076,15 +1077,18 @@ with_item:
10761077
except_clause:
10771078
EXCEPT
10781079
{
1079-
// FIXME
1080+
$$ = nil
1081+
$<str>$ = ""
10801082
}
10811083
| EXCEPT test
10821084
{
1083-
// FIXME
1085+
$$ = $2
1086+
$<str>$ = ""
10841087
}
10851088
| EXCEPT test AS NAME
10861089
{
1087-
// FIXME
1090+
$$ = $2
1091+
$<str>$ = $4
10881092
}
10891093

10901094
stmts:

parser/grammar_test.go

+6
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,12 @@ func TestGrammar(t *testing.T) {
208208
{"for a in b: pass", "exec", "Module(body=[For(target=Name(id='a', ctx=Store()), iter=Name(id='b', ctx=Load()), body=[Pass()], orelse=[])])"},
209209
{"for a, b in b: pass", "exec", "Module(body=[For(target=Tuple(elts=[Name(id='a', ctx=Store()), Name(id='b', ctx=Store())], ctx=Store()), iter=Name(id='b', ctx=Load()), body=[Pass()], orelse=[])])"},
210210
{"for a, b in b:\n pass\nelse: break\n", "exec", "Module(body=[For(target=Tuple(elts=[Name(id='a', ctx=Store()), Name(id='b', ctx=Store())], ctx=Store()), iter=Name(id='b', ctx=Load()), body=[Pass()], orelse=[Break()])])"},
211+
{"try:\n pass\nexcept:\n break\n", "exec", "Module(body=[Try(body=[Pass()], handlers=[ExceptHandler(type=None, name=None, body=[Break()])], orelse=[], finalbody=[])])"},
212+
{"try:\n pass\nexcept a:\n break\n", "exec", "Module(body=[Try(body=[Pass()], handlers=[ExceptHandler(type=Name(id='a', ctx=Load()), name=None, body=[Break()])], orelse=[], finalbody=[])])"},
213+
{"try:\n pass\nexcept a as b:\n break\n", "exec", "Module(body=[Try(body=[Pass()], handlers=[ExceptHandler(type=Name(id='a', ctx=Load()), name='b', body=[Break()])], orelse=[], finalbody=[])])"},
214+
{"try:\n pass\nexcept a:\n break\nexcept:\n continue\nexcept b as c:\n break\nelse:\n pass\n", "exec", "Module(body=[Try(body=[Pass()], handlers=[ExceptHandler(type=Name(id='a', ctx=Load()), name=None, body=[Break()]), ExceptHandler(type=None, name=None, body=[Continue()]), ExceptHandler(type=Name(id='b', ctx=Load()), name='c', body=[Break()])], orelse=[Pass()], finalbody=[])])"},
215+
{"try:\n pass\nexcept:\n continue\nfinally:\n pass\n", "exec", "Module(body=[Try(body=[Pass()], handlers=[ExceptHandler(type=None, name=None, body=[Continue()])], orelse=[], finalbody=[Pass()])])"},
216+
{"try:\n pass\nexcept:\n continue\nelse:\n break\nfinally:\n pass\n", "exec", "Module(body=[Try(body=[Pass()], handlers=[ExceptHandler(type=None, name=None, body=[Continue()])], orelse=[Break()], finalbody=[Pass()])])"},
211217
// END TESTS
212218
} {
213219
Ast, err := ParseString(test.in, test.mode)

parser/make_grammar_test.py

+48
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,54 @@
252252
("for a in b: pass", "exec"),
253253
("for a, b in b: pass", "exec"),
254254
("for a, b in b:\n pass\nelse: break\n", "exec"),
255+
("""\
256+
try:
257+
pass
258+
except:
259+
break
260+
""", "exec"),
261+
("""\
262+
try:
263+
pass
264+
except a:
265+
break
266+
""", "exec"),
267+
("""\
268+
try:
269+
pass
270+
except a as b:
271+
break
272+
""", "exec"),
273+
("""\
274+
try:
275+
pass
276+
except a:
277+
break
278+
except:
279+
continue
280+
except b as c:
281+
break
282+
else:
283+
pass
284+
""", "exec"),
285+
("""\
286+
try:
287+
pass
288+
except:
289+
continue
290+
finally:
291+
pass
292+
""", "exec"),
293+
("""\
294+
try:
295+
pass
296+
except:
297+
continue
298+
else:
299+
break
300+
finally:
301+
pass
302+
""", "exec"),
255303
]
256304

257305
def dump(source, mode):

0 commit comments

Comments
 (0)