识别彼此相邻的无限'{' expr '}'的语法



我正在使用ANTLR4编写一个c#应用程序来识别以下TeX'ish风格:

{一}{x} + {b} {y} + {c}

我当前的语法总是取'{' expr '}'的最后一个实例,然后忽略字符串的开始。下面是当前语法的一些输出结果(如下所述):

    输入:
  • {一}输出:(通过)
  • 输入:
  • {一}+ {x} 输出: + x (通过)
  • 输入:
  • {一}{x} 输出: x (失败)期望: ax
  • 输入:
  • {一}{x} + {b} 输出: x + b (失败)期望: ax + b
  • 输入:
  • {一}{x} + {b} {y} 输出: y (失败)期望: ax + by
  • 输入:
  • {一}{x} + {b} {y} + {c} 输出: y + c (失败)期望: ax + by + c
  • 输入:
  • {一}{x} + {b} {y} + c {} {d} 输出: d (失败)期望: ax + by + cd

有什么办法解决这个问题吗?

语法MyGra。g4文件:

/*
 * 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文件:

 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:

建议为

添加一个语法规则
'{' expr '}{' expr '}'

然而,如果我有{a}{b}{c}{d}+{e}{f}{g},我认为语法应该通过解析树解释递归版本的"自身"……那么如果我有1000个{expr}挨个呢?那么我需要多少条规则呢?我认为这个建议是有效的,除了我不确定如何解释相邻的无限数量的{expr} ?

我的另一个问题是:我如何重用规则CB_Expr?

更新# 2:

我添加了规则:

| expr CB_Expr                  # CB_Expr2
与参观者:

public override string VisitCB_Expr2(MyGra.CB_Expr2Context context)
{
    return Visit(context.expr()) + Visit(context.CB_Expr());
}

这没有帮助,对于所有情况我仍然得到相同的输出(如上所述)。

你的语法有歧义。例如:输入{x}可以有两个不同的解析树(如Mephy所说):

(CB_Expr {(expr (ID x))})

(DB_ID {x})

删除CB_ID将修复这个问题,而不会实际做任何负面的事情。

对于您的实际问题,这应该可以解决expr的问题:

expr : left=id_expr op=('+' |'-') right=expr #AddSub
     | id_expr                               #ID_Expr
     ;
id_expr :
     | '{' ID '}' id_expr                    #ID_Ex
     | '{' ID '}'                            #ID
     ;

我还没有测试过这个,我也没有给你写任何访客,但是语法应该是有效的。

id_expr规则递归地工作,因此您应该能够在每个{ID}后面放置尽可能多的{ID} -尽管至少有一个,但语法现在是这样的。

相关内容

  • 没有找到相关文章

最新更新