Antlr4 如何在解析期间检查ID是否有效-未调用ParseTreeListener enter事件

Antlr4 如何在解析期间检查ID是否有效-未调用ParseTreeListener enter事件,antlr4,Antlr4,我的语法包含以下内容: assignment : ID ASSIGN expr ; expr : MINUS expr #unaryMinusExpr | NOT expr #notExpr | expr MULT expr #multExpr | expr DIV expr #divExpr | expr PLUS expr #plusExp

我的语法包含以下内容:

assignment
: ID ASSIGN expr
;

expr
 : MINUS expr                 #unaryMinusExpr
 | NOT expr                   #notExpr
 | expr MULT expr             #multExpr
 | expr DIV expr              #divExpr
 | expr PLUS expr             #plusExpr
 | expr MINUS expr            #minusExpr
 | expr LTEQ expr             #lteqExpr
 | expr GTEQ expr             #gteqExpr
 | expr LT expr               #ltExpr
 | expr GT expr               #gtExpr
 | expr NEQ expr              #neqExpr
 | expr EQ expr               #eqExpr
 | expr AND expr              #andExpr
 | expr OR expr               #orExpr
 | atom                       #atomExpr
 ;

atom
 : OPAR expr CPAR #parExpr
 | (INT | FLOAT)  #numberAtom
 | (TRUE | FALSE) #booleanAtom
 | STRING         #stringAtom
 | ID             #idAtom
 ;

ID
 : [a-zA-Z_] [a-zA-Z_0-9]*
 ;
这里的ID表示数据库中的一个条目(行),用户通过,嗯:),ID引用该条目。因此,在解析公式时,我想检查他们是否输入了有效的ID

据我所知,方法是使用一个覆盖EnterIdAtom的ParseTreeListener,这样我就可以抛出一个RecognitionException。所以我连接了它,但从未调用Enter事件

class MyListener : BaseListener
{
     public override EnterIdAtom(IdAtomContext context)
     {
          if (!CheckForValidId(context.ID().GetText())
          {
               throw new RecognitionException(...)
          }
     }
}
不知道为什么

有更好的方法吗


谢谢。

您是否已将断点设置为:

public override void enterEveryRule(ParserRuleContext ctx)

如果规则被调用,这将为您提供线索

否则,请尝试以下操作:

atom
 : OPAR expr CPAR #parExpr
 | (INT | FLOAT)  #numberAtom
 | (TRUE | FALSE) #booleanAtom
 | STRING         #stringAtom
 | atomId            // changed!
 ;


atomId
 :  ID
 ;
这将生成一个新的“真实”上下文,您可以访问:

public override void enterAtom(AtomIdContext ctx) {}

听起来您正在使用(我添加的粗体字体):

注册侦听器以在解析过程中接收事件

为了支持保留输出的语法转换(包括但不限于左递归移除、自动左因子分解和优化的代码生成),解析期间对侦听器方法的调用可能与解析完成后使用的
ParseTreeWalker.DEFAULT
调用大不相同。特别是,规则进入和退出事件在解析期间的发生顺序可能与在解析器之后的发生顺序不同此外,可以省略对某些规则输入方法的调用。

除了以下特定的例外,对侦听器事件的调用是确定的,即对于相同的输入,对侦听器方法的调用将是相同的

  • 更改用于生成代码的语法可能会更改侦听器调用的行为
  • 在生成解析器时,对传递给ANTLR 4的命令行选项的更改可能会更改侦听器调用的行为
  • 更改用于生成解析器的ANTLR工具的版本可能会更改侦听器调用的行为

如果是这种情况,您应该在解析完成后使用
ParseTreeWalker
遍历树,而不是尝试将这两个操作混合在一起。

您可以为您的
ParseTreeListener
发布一些代码吗?虽然我更喜欢一个解析树行者,如果在解析后可以进行更改。。。您还可以检查lexer操作()。这将允许lexer在lexing时检查ID,尽管我不会这样做。添加了示例代码。如果有一种方法可以在lexer完成后简单地获得一个列表,那也可以。类似lexer.GetListOfIdAtoms()的东西非常感谢!有道理。一个快速相关的问题。有没有一种简单的方法可以从解析器、树或walker获取ID列表?虽然我可以在我的听者中跟踪它们,但我想我应该检查一下是否已经有一种内置的方法可以做到这一点?找到以下帖子:
public override void enterAtom(AtomIdContext ctx) {}