[英]How to deactivate tokens with 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>`
我认为您在添加谓词后忘记重新生成解析器类。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.