Closed mewmew closed 8 years ago
Updated by commit 072e46b3b99e8c481a102f9eb8c03195757b1150.
This issue is not yet resolved, however, as is made apparent when trying to parse quiet/lexer/l05.c
.
u@x1 ~/D/g/s/g/m/uc> uparse testdata/quiet/lexer/l05.c
Parsing "testdata/quiet/lexer/l05.c"
…
S26 {(13,{) shift:32
pos: 19
typ: 11
lit: int
S32 int(11,int) shift:9
pos: 23
typ: 4
lit: i
S9 ident(4,i) reduce:11(TypeName : "int" << >>)
S37 ident(4,i) shift:40
pos: 24
typ: 3
lit: ;
S40 ;(3,;) reduce:8(ScalarDecl : TypeName ident << >>)
S6 ;(3,;) reduce:6(VarDecl : ScalarDecl << >>)
S36 ;(3,;) shift:39
pos: 28
typ: 8
lit: 1
S39 int_lit(8,1) reduce:21(Locals : empty << >>)
S62 int_lit(8,1) reduce:22(Locals : VarDecl ";" Locals << >>)
S38 int_lit(8,1) shift:44
pos: 29
typ: 30
lit: !=
S44 !=(30,!=) reduce:57(Expr1 : int_lit << >>)
S61 !=(30,!=) reduce:55(Expr2R : Expr1 << >>)
S60 !=(30,!=) reduce:53(Expr5L : Expr2R << >>)
S59 !=(30,!=) reduce:50(Expr9L : Expr5L << >>)
S58 !=(30,!=) shift:99
pos: 31
typ: 21
lit: !
2016/04/04 17:16:28 main.parseFile (uparse.go:71): error: Error in S99: !(21,!), Pos(offset=31, line=5, column=10), expected one of: ident ( int_lit
As of commit 1727d79 the precedence order has been corrected. However, we still need to find a solution for handling left- and right-associativity. The uC language has a single expression which requires right-associativity, namely the assignment expression. For now, finding a solution to this remains an open topic for discussion.
Below follows an example which demonstrates the current (incorrect) behaviour of parsing assignment expressions, which should be right-associative, but are treated as left-associative like all the other expressions.
Relevant sections of the input file testdata/quiet/parser/p01.c
and the output of the uparse
command have been included below.
Line 5 of testdata/quiet/parser/p01.c:
x=y=4711;
u@x1 ~/D/g/s/g/m/uc> uparse testdata/quiet/parser/p01.c
Parsing "testdata/quiet/parser/p01.c"
…
&ast.ExprStmt{
X: &ast.BinaryExpr{
X: &ast.BinaryExpr{
X: &ast.Ident{Name:"x"},
Op: 0xd,
Y: &ast.Ident{Name:"y"},
},
Op: 0xd,
Y: &ast.BasicLit{Kind:0x5, Val:"4711"},
},
},
The parse tree before and after applying commit 2cba9fc, which fixes the right-associativity of assignment expressions.
Before:
u@x1 ~/D/g/s/g/m/uc> uparse testdata/quiet/parser/p01.c
Parsing "testdata/quiet/parser/p01.c"
=== [ Top-level declaration ] ===
decl type: *ast.FuncDecl
decl: &{0xc8200aa750 0xc8200126c0 0xc82000a560}
&ast.FuncDecl{
Name: &ast.Ident{Name:"main"},
Type: &types.Func{
Params: nil,
Result: &types.Basic{Kind:2},
},
Body: &ast.BlockStmt{
Stmts: {
&ast.DeclStmt{
Decl: &ast.VarDecl{
Type: &types.Basic{Kind:2},
Name: &ast.Ident{Name:"x"},
Val: nil,
},
},
&ast.DeclStmt{
Decl: &ast.VarDecl{
Type: &types.Basic{Kind:2},
Name: &ast.Ident{Name:"y"},
Val: nil,
},
},
&ast.ExprStmt{
X: &ast.BinaryExpr{
X: &ast.Ident{Name:"x"},
Op: 0xd,
Y: &ast.BasicLit{Kind:0x5, Val:"42"},
},
},
&ast.ExprStmt{
X: &ast.BinaryExpr{
X: &ast.BinaryExpr{
X: &ast.Ident{Name:"x"},
Op: 0xd,
Y: &ast.Ident{Name:"y"},
},
Op: 0xd,
Y: &ast.BasicLit{Kind:0x5, Val:"4711"},
},
},
},
},
}
<*>{<*>{main} <*>{<nil> <*>{Int}} <*>{[<*>{<*>{<*>{Int} <*>{x} <nil>}} <*>{<*>{<*>{Int} <*>{y} <nil>}} <*>{<*>{<*>{x} Assign <*>{IntLit 42}}} <*>{<*>{<*>{<*>{x} Assign <*>{y}} Assign <*>{IntLit 4711}}}]}}
After:
u@x1 ~/D/g/s/g/m/uc> uparse testdata/quiet/parser/p01.c
Parsing "testdata/quiet/parser/p01.c"
=== [ Top-level declaration ] ===
decl type: *ast.FuncDecl
decl: &{0xc8200a2110 0xc8200a8180 0xc820098120}
&ast.FuncDecl{
Name: &ast.Ident{Name:"main"},
Type: &types.Func{
Params: nil,
Result: &types.Basic{Kind:2},
},
Body: &ast.BlockStmt{
Stmts: {
&ast.DeclStmt{
Decl: &ast.VarDecl{
Type: &types.Basic{Kind:2},
Name: &ast.Ident{Name:"x"},
Val: nil,
},
},
&ast.DeclStmt{
Decl: &ast.VarDecl{
Type: &types.Basic{Kind:2},
Name: &ast.Ident{Name:"y"},
Val: nil,
},
},
&ast.ExprStmt{
X: &ast.BinaryExpr{
X: &ast.Ident{Name:"x"},
Op: 0xd,
Y: &ast.BasicLit{Kind:0x5, Val:"42"},
},
},
&ast.ExprStmt{
X: &ast.BinaryExpr{
X: &ast.Ident{Name:"x"},
Op: 0xd,
Y: &ast.BinaryExpr{
X: &ast.Ident{Name:"y"},
Op: 0xd,
Y: &ast.BasicLit{Kind:0x5, Val:"4711"},
},
},
},
},
},
}
<*>{<*>{main} <*>{<nil> <*>{Int}} <*>{[<*>{<*>{<*>{Int} <*>{x} <nil>}} <*>{<*>{<*>{Int} <*>{y} <nil>}} <*>{<*>{<*>{x} Assign <*>{IntLit 42}}} <*>{<*>{<*>{x} Assign <*>{<*>{y} Assign <*>{IntLit 4711}}}}]}}
From
LR1_conflicts.txt
generated by Gocc:Relevant production rules from the BNF grammar:
Example which fails to parse using
uparse
on input testdata/quiet/parser/p04.c:Still looking for a good solution to this issue.