Reputation: 1587
I was writing LOLCODE interpreter and got stuck with a problem. In LOLCODE function calls look like:
<func_name> <arg1> <arg2> ....
myfunc 1 2 3
Let's consider that myfunc take three args. I do not know how to support such a construction:
VISIBLE myfunc 1 2 3 4
I want bison to parse it like that:
myfunc 1 2 3 -> function
4 -> expr
I declared function call as:
ID expr_list { $$ = new ExprFunctionCall($1, $2); }
where expr_list is:
expr_list
: expr_list expr { $$->putExpr($2); }
| /* epsilon */ { $$ = new ExprList(); }
;
How can I tell bison where to stop if I know declared function arity?
Upvotes: 0
Views: 129
Reputation: 119847
You can't do it in bison. Not cleanly anyway. Bison is a tool to parse context-free languages, and yours is context-dependent.
Sometimes you can bend the rules and shove some context dependency in there, as is the case with C and C++, but in your case it's probably worth investigating other parser generators. If you want to do it anyway, introduce an explicit token to end the function call, and another helper symbol to process a function argument. This special token is not something found in the source, it's injected by the lexer at the request of the parser.
The rules should look roughly like this (untested, the grammar is likely not to work on the first try, but the general idea is this):
call
: function expr_list { ... }
;
function
: ID { ... push function arity on some stack somewhere }
expr_list
: expr_list pre_expr expr { ... }
| pre_expr END_LIST { ... }
;
pre_expr
: /* epsilon */ { ... decrease function arity on the top of the stack
if it's zero,
tell the lexer to issue END_LIST token next
and pop the arity off the stack
}
;
Upvotes: 3