I have a YACC grammar for parsing expressions in C++. Here is lite version:
// yacc.y
%token IDENT
%%
expr:
call_expr
| expr '<' call_expr
| expr '>' call_expr
;
call_expr:
IDENT
| '(' expr ')'
| IDENT '<' args '>' '(' args ')'
;
args:
IDENT
| args ',' IDENT
;
%%
When I want to support function call with template arguments, I got a shift/reduce
conflict.
When we got input IDENT '<' IDENT
, yacc doesn't know whether we should shift or reduce.
I want IDENT '<' args '>' '(' args ')'
got higher precedence level than expr '<' call_expr
, so I can parse the following exprs.
x < y
f<x>(a,b)
f<x,y>(a,b) < g<x,y>(c,d)
I see C++/C# both support this syntax. Is there any way to solve this problem with yacc?
How do I modify the .y
file?
Thank you!
yacc
. If you usebison
and switch to GLR mode, you should be able to parse it. – templatetypedeff<x>(a)
without knowing whetherf
is a template or not. All GLR can do is provide you with both possible parses (which will turn into an exponential number of parses for the full program). – riciTEMPLATE_ID '<' expr_list '>'
. (That means you need to information available in your lexer, so the lexer and the parser need to share a symbol table. No big deal.) (And, yes, I'm leaving out lots of details.) (And you could do it the way you suggest with GLR, but I suspect it would be even more complicated.) – ricif
is (at least, in my example). – riciif_both(x<1, y>(x+1)*(x+1), 42)
. Personally, I'd go withD
, which doesn't make<
ambiguous. – rici