Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/373.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java ANTLR4是否仍然支持无扫描解析器语法?_Java_Parsing_Antlr4 - Fatal编程技术网

Java ANTLR4是否仍然支持无扫描解析器语法?

Java ANTLR4是否仍然支持无扫描解析器语法?,java,parsing,antlr4,Java,Parsing,Antlr4,我有一个利用faux lexer的无扫描解析器语法,它为ANTLR4到4.6版本生成了一个可用的Java解析器类。但是当更新到ANTLR 4.7.2到4.9.3-SNAPSHOT时,该工具生成的代码会从同一语法文件中产生几十个编译错误,如下所述 我这里的问题很简单:是否不再支持无扫描解析器语法,或者是否必须在4.7及更高版本中以不同方式指定其基于字符的终端 更新: 不幸的是,我无法在此发布我的完整语法,因为它源自FOUO安全标记指南,美国政府(我是国防部/IC承包商)对其进行了审查 然而,不兼容

我有一个利用faux lexer的无扫描解析器语法,它为ANTLR4到4.6版本生成了一个可用的Java解析器类。但是当更新到ANTLR 4.7.2到4.9.3-SNAPSHOT时,该工具生成的代码会从同一语法文件中产生几十个编译错误,如下所述

我这里的问题很简单:是否不再支持无扫描解析器语法,或者是否必须在4.7及更高版本中以不同方式指定其基于字符的终端

更新:

不幸的是,我无法在此发布我的完整语法,因为它源自FOUO安全标记指南,美国政府(我是国防部/IC承包商)对其进行了审查

然而,不兼容的升级问题完全可以通过本标准第5.6节中Ter提到的无扫描解析器语法示例重现

和我的语法一样,CSQL示例将其用作标记器和标记词汇表

请注意,每个令牌名称都由其ASCII字符文字等效物指定,如中所示:

'\*'=42
'+'=43
解析器语法直接在其规则中引用引用的标记名,如:

star: '*' ws? ;
plus: '+' ws? ;
这里的问题是,使用ANTLR4版本4.2到4.6会从这些语法生成可编译的解析器类,而ANTLR v4.7.2及更高版本会生成带有大量错误的Java代码

以下是ANTLR v4.6生成的可用CSQL Java类定义中的一个片段:

 public static class ArgsContext extends ParserRuleContext {
      public List<ArgContext> arg() {
          return getRuleContexts(ArgContext.class);
      }
      public ArgContext arg(int i) {
          return getRuleContext(ArgContext.class,i);
      }
      public ArgsContext(ParserRuleContext parent, int invokingState) {
          super(parent, invokingState);
      }
      @Override public int getRuleIndex() { return RULE_args; }
      @Override
      public void enterRule(ParseTreeListener listener) {
          if ( listener instanceof CSQLListener ) ((CSQLListener)listener).enterArgs(this);
      }
      @Override
      public void exitRule(ParseTreeListener listener) {
          if ( listener instanceof CSQLListener ) ((CSQLListener)listener).exitArgs(this);
      }
 }

那么,为什么要在ANTLR v4.7+中进行向后不兼容的更改,以及我应该如何最好地解决它呢?

尝试定义一个GrammarLexer.g4文件,而不是GrammarLexer.tokens文件。(您仍然可以像创建GrammarLexer.tokens文件一样使用
选项:{tokenVocab=GrammarLexer;}
。}它可以简单到:

T1 : ' ';
T2 : '\n';
T3 : '\r';
T4 : 'a';
T5 : 'b';
这将为您创建令牌名称。Antlr将允许您在解析器语法规则中包含
'a'
'\n'
等,但将它们与lexer语法中的lexer规则名称匹配并使用该名称(例如:
T4
当您的规则中有
'a'
时,以及
T2
当您有
'\n'
时),这样它将编译干净。您不必使用lexer,只要您的
CharsAsTokens
产生相同的令牌值。(不过,仔细想想,这个杠杆可能相当于您正在使用的
CharsAsTokens
tokenizer,并保证令牌编号匹配。)


这似乎仍然可以实现您的目标,即标记只是一个字符流,并处理解析器规则中的所有内容。(并且不会比生成*.tokens文件更繁重。两者都需要是所有有效字符的详尽列表。)

你能发布一个完整的语法来说明你的问题吗?旁注:你怎么会称之为“无扫描”?
CharAsTokens
是一个简化的令牌源,但仍然是一个令牌源(因此也是一个扫描器)。你的问题可能不是关于支持“无扫描解析器”(无论在本文中是什么意思),但ANTLR较新版本中的一些更改会在生成的代码中产生语法错误。因此,请给出错误的示例以及语法的相关部分。您不能在令牌文件中定义字符串文字,而在解析器语法文件中使用字符串文字。例如,在.tokens文件中
''=1'\n'=2'\r'=3…
和解析器文件
parser grammar ArithmeticParser;选项{tokenVocab=ArithmeticLexer;}ws:('''.'\r'.'.'\n')+;
。您必须使用令牌名称而不是文字(
ws:'SP | CR | LF)
),然后你可以使用4.9.2。理想情况下,你只需要一个lexer语法来声明所有这些,但不要使用lexer。然后我的trfoldlit垃圾可以自动更改你的解析器语法。或者直接手工完成。(实际上,程序还不能处理拆分语法文字展开。我将修复一个错误。现在,您只需手动展开解析器语法中的字符串文字,并在.tokens文件中声明标记名称。)@Bart Kiers我已经用一个更简单但相似的语法的完整示例更新了问题陈述,以及我的代码使用的相同的标记器和标记词汇表。死吧,Mike——漂亮的解决方案!通过将新的lexer语法命名为CharVocab.g4,CharVocab.tokens文件只需由ANTLR工具重新生成一次。然后,所有existing解析器语法使用它和CharsAsTokens faux lexer将在不修改语法或标记器的情况下运行!对于希望在不修改的情况下使用原始CharsAsTokens标记器的任何人,有一个警告:您需要确保用于生成CharVocab.tokens的CharVocab.g4文件定义其规则,以便第n个规则对应ds到关联终端的第n个字符索引。例如,由于“\t”是第9个ASCII字符,“T9:'\t';”前面必须有T1到T8占位符规则,如“T1:'\u0001';”、“T2:'\u0002';”等。这将保留令牌的字符文本及其令牌类型的等效性,即token.getText()。charAt(0)=(char)token.getType()。
Syntax error on token "','", Identifier expected  CSQL.java     /CSQL/generated-sources  line 446  Java Problem
Syntax error on token "','", delete this token    CSQL.java     /CSQL/generated-sources  line 447  Java Problem
CSQL cannot be resolved to a variable   CSQL.java /CSQL/generated-sources     line 448  Java Problem
Syntax error on token ".", , expected   CSQL.java /CSQL/generated-sources     line 448  Java Problem
T1 : ' ';
T2 : '\n';
T3 : '\r';
T4 : 'a';
T5 : 'b';