c# - Grammar to recognize unlimited '{' expr '}' next to each-other -


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