简体   繁体   English

javascript:如何在antlr生成的Lexer中进行错误处理?

[英]javascript : How to do Error Handling in Lexer generated by antlr?

I am writing a java script grammar parser using antlr. 我正在使用antlr编写一个java脚本语法分析器。 Antlr creates a method for each token in lexer . Antlr为词法分析器中的每个标记创建一个方法。 But it does not contain a catch block. 但它不包含catch块。 I want to add customize catch block to lexer methods. 我想为lexer方法添加自定义catch块。 I have added customized catch block for parser methods , but not able to add it for lexer methods through grammar file. 我为解析器方法添加了自定义catch块,但是无法通过语法文件为lexer方法添加它。

Here is grammar file - 这是语法文件 -

grammar test;

options {
 language=JavaScript;
 output=AST;
}
@lexer::members {
  function reportError(e) {
    throw e;
  }
}
SALUTATION:'Hello world';  
ENDSYMBOL:'!';
expression : SALUTATION ENDSYMBOL;
catch [e] {
  throw e;
}

And complete demo here - Plunker 并在此完成演示 - Plunker

TL;DR TL; DR

Lexer is different than parser - Lexer与解析器不同 -

  • When a parser finds an unexpected input, it is in some rule and knows that should have been on the input next 当解析器发现意外输入时,它在某个规则中并且知道接下来应该在输入上
  • When a lexer finds an unexpected input, that means that none of the defined lexer rules match the input (that is lexer's definition of "unexpected" - remember that lexer only cares about matching the next "word" on input and doesn't care about what was matched before) - and since the problem is "none of the rules match this", it doesn't make sense to ask "In which lexer rule the problem occurred?" 当词法分析器发现意外输入时,这意味着没有任何已定义的词法分析器规则与输入匹配(这是词法分析器对“意外”的定义 - 请记住,词法分析器只关心匹配输入上的下一个“单词”而不关心之前匹配的内容) - 并且因为问题是“没有一个规则符合这个”,所以问“问题发生在哪个词法分析器规则中”是没有意义的。

And because you cannot tell in which lexer rule an unexpected input occurred, there's no point in adding a catch block to them. 并且因为您无法判断出哪个词法分析器规则发生了意外输入,所以向它们添加catch块是没有意义的。


Long explanation 很长的解释

Adding catch blocks to methods for lexer rules doesn't make much sense. 将catch块添加到词法分析器规则的方法没有多大意义。 The reason is that the lexer methods are used in a different way than parser methods - this is what happens when the parser queries for the next token: 原因是lexer方法的使用方式与解析器方法不同 - 这是解析器查询下一个标记时发生的情况:

  • org.antlr.runtime.Lexer.nextToken() is called - this method will run the lexer using mTokens() and then collect the result org.antlr.runtime.Lexer.nextToken() - 此方法将使用mTokens()运行词法分析器,然后收集结果
  • mTokens() method in your lexer decides which token rule is appropriate and runs it 词法分析器中的mTokens()方法决定哪个令牌规则是合适的并运行它
    • The decision is done in mTokens() (usually through a DFA - finite automate), not in the lexer rule methods 决定是在mTokens() (通常通过DFA - 有限自动机),而不是在词法分析器规则方法中
      • This will throw NoViableAlt exception if no lexer rule matches the current input 如果没有词法分析器规则与当前输入匹配,则会抛出NoViableAlt异常
  • Appropriate lexer rule method consumes the input and sets the appropriate flags for nextToken() to use as the lexer result 适当的词法分析器规则方法使用输入并为nextToken()设置适当的标志以用作词法分析器结果
    • While this method may throw an exception as well, this should normally never happen since the decision in mTokens() should already choose a matching rule 虽然这个方法也可能抛出一个异常,但这通常不会发生,因为mTokens()的决定应该已经选择了匹配规则

My understanding is that unless you use syntactic or semantic predicates or custom code in your lexer rules, the lexer rule methods should never actually throw a RecognitionException - the place where these are emitted should be the decision block in mTokens() . 我的理解是,除非你在词法分析器规则中使用语法或语义谓词或自定义代码,否则词法分析器规则方法实际上不应该抛出一个RecognitionException - 它们发出的位置应该是mTokens()的决策块。 So adding a catch block to lexer rule methods makes no sense. 因此,为词法分析器规则方法添加一个catch块是没有意义的。


mTokens() has no try block around the decision-making part, so no custom catch block is possible unless you modify the code-generation templates. mTokens()在决策部分没有try阻止,因此除非您修改代码生成模板,否则不可能有自定义catch块。 You could try to override org.antlr.runtime.Lexer.nextToken() with your own method with custom exception handling, but there you will only be able to provide one catch block for all lexer rules, not for one specific rule. 您可以尝试使用自己的方法使用自定义异常处理覆盖org.antlr.runtime.Lexer.nextToken() ,但是您只能为所有词法分析器规则提供一个catch块,而不是针对一个特定规则。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM