java - 如何使用 Antlr4 停用令牌
问题描述
我必须用 antlr4 解析一个由许多数据块组成的文本文件,每个数据块都有一个数据块头(一行)和几个数据行,(1..*)行。
数据块标头始终以位于行的第一个位置的“1”为星号,然后是几个字母数字字段。
DataRow 也是由字母数字字段 (dataFields) 组成,字符 '1' 可以是第一个 dataField 但永远不会位于行的第一个位置。
这是要解析的输入示例:
1 DataHeaderField1 datafield2 DataBlock1
DB1_Row1_F1 DB1_Row1_F2 DB1_Row1_F3 DataBlock1
DB1_Row2_F1 DB1_Row2_F2 DB1_Row2_F3 DataBlock1
1 DataHeaderField1 datafield2 DataBlock2
DB2_Row1_F1 DB2_Row1_F2 DB2_Row1_F3 DataBlock2
DB2_Row2_F1 DB2_Row2_F2 DB2_Row2_F3 DataBlock2
DB2_Row3_F1 DB2_Row3_F2 DB2_Row3_F3 DataBlock2
....
我试过的语法是:
grammar ReadDataBlocks;
start_parsing: dataBlock+ EOF;
dataBlock: commonHeader row+;
commonHeader: ONE_AT_FIRST_POS APLHANUMERIC* NL ;
row: APLHANUMERIC+ NL;
ONE_AT_FIRST_POS: '1' {getCharPositionInLine() == 1}?;
APLHANUMERIC : (LETTER
|
DIGIT)+;
DIGIT: [0-9];
LETTER: [a-zA-Z];
NL: '\r'? '\n';
ESPACES : [ \t]+ -> skip;
为了解析文件,我在词法分析器中停用了标记,如我的语法所示,通过在 DIGIT 标记之前指定标记 ONE_AT_FIRST,因此在任何时候在第一个位置检测到“1”时都不会被解析为 DIGIT。
问题是,当解析器运行位于任何其他位置的“1”时,仍然标识为 ONE_AT_FIRST_POS 并抛出以下消息:
解决方案
运行后:
public class Main {
public static void main(String[] args) {
String source = "1 headerData1 headData2 HeadDataN\n row1Data Row2Data 1 333 rowNData";
Lexer lexer = new ReadDataBlocksLexer(CharStreams.fromString(source));
CommonTokenStream tokens = new CommonTokenStream(lexer);
tokens.fill();
for (Token t : tokens.getTokens()) {
System.out.printf("%-20s `%s`\n", ReadDataBlocksLexer.VOCABULARY.getSymbolicName(t.getType()), t.getText());
}
}
}
我得到以下输出:
ONE_AT_FIRST_POS `1`
APLHANUMERIC `headerData1`
APLHANUMERIC `headData2`
APLHANUMERIC `HeadDataN`
NL `
`
APLHANUMERIC `row1Data`
APLHANUMERIC `Row2Data`
APLHANUMERIC `1`
APLHANUMERIC `333`
APLHANUMERIC `rowNData`
EOF `<EOF>`
我认为您在添加谓词后忘记重新生成解析器类。
推荐阅读
- maxima - wxMaxima:函数中的子索引变量在写为“x_1”时有效,但在写为“x[1]”时无效
- python - 如何删除包含公共元素的子列表?
- amazon-web-services - AWS Amplify 归属关系和过滤
- r - `cor(data) 中的错误:'x' 必须是相关代码中的数字`
- mysql - 本地/实时站点上的相同查询,性能大不相同
- c++11 - 如何修复错误soft_int/src_int.h:没有这样的文件或目录?
- ios - SwiftUI 简单视图,需要朝着正确的方向推进
- c++ - 如何修复这个未定义的引用错误?
- javascript - Eslint 忽略所有 exept js 文件
- javascript - 如何遍历类型化数组?