i writing c# application using antlr4 recognize following tex'ish style:
{a}{x}+{b}{y}+{c}
my current grammar takes last instance of '{' expr '}' ignores beginning of string. here output results current grammar (described below):
- input: {a} output: [pass]
- input: {a}+{x} output: + x [pass]
- input: {a}{x} output: x [fail] desired: ax
- input: {a}{x}+{b} output: x + b [fail] desired: ax + b
- input: {a}{x}+{b}{y} output: y [fail] desired: ax + by
- input: {a}{x}+{b}{y}+{c} output: y + c [fail] desired: ax + + c
- input: {a}{x}+{b}{y}+{c}{d} output: d [fail] desired: ax + + cd
any ideas on how fix this?
grammar mygra.g4 file:
/* * parser rules */ prog: expr+ ; expr : '{' expr '}' # cb_expr | expr op=('+'|'-') expr # addsub | '{' id '}' # cb_id | id # id ; /* * lexer rules */ id: ('a' .. 'z' | 'a' .. 'z')+; add : '+'; sub : '-'; ws: (' ' | '\r' | '\n') -> channel(hidden);
mygravisitor.cs file:
public override string visitid(mygraparser.idcontext context) { return context.id().gettext(); } public override string visitaddsub(mygraparser.addsubcontext context) { if (context.op.type == mygraparser.add) { return visit(context.expr(0)) + " + " + visit(context.expr(1)); } else { return visit(context.expr(0)) + " - " + visit(context.expr(1)); } } public override string visitcb_expr(mygraparser.cb_exprcontext context) { return visit(context.expr()); } public override string visitcb_id(mygraparser.cb_idcontext context) { return context.id().gettext(); }
update #1:
it suggested include grammar rule
'{' expr '}{' expr '}'
however, if have {a}{b}{c}{d}+{e}{f}{g}, thought grammar supposed account recursive versions of "itself" via parse trees... if have 1000 {expr}'s next each-other? how many rules need then? think suggestion valid, except not sure how account unlimited amounts of {expr} next each-other?
another question have is: how can re-use rule cb_expr?
update #2:
i added rule:
| expr cb_expr # cb_expr2
with visitor:
public override string visitcb_expr2(mygra.cb_expr2context context) { return visit(context.expr()) + visit(context.cb_expr()); }
that did not help, still same output cases (described above).
your grammar ambigous. example: input {x} can have 2 different parse trees (as mephy said):
(cb_expr { (expr (id x)) })
and
(db_id {x})
removing cb_id fix without doing negative.
for actual problem, should trick expr:
expr : left=id_expr op=('+' |'-') right=expr #addsub | id_expr #id_expr ; id_expr : | '{' id '}' id_expr #id_ex | '{' id '}' #id ;
i have not tested though, , have not written visitors, grammar should work.
the id_expr rule works recursively, should able put many {id} after each other want - @ least 1 though, way grammar right now.
Comments
Post a Comment