Java 复杂文件解析中的Antlr Lexer回溯

Java 复杂文件解析中的Antlr Lexer回溯,java,antlr,antlr3,Java,Antlr,Antlr3,我们使用ANTLR解析复杂的文件结构,然后创建java对象来执行某些活动 到目前为止,文件中的每一行都以标识符开头。例如: 第1行…\n 第2行…\n EOF 现在有了新的要求,线路的标识符,即线路1等,可以出现在线路的任何部分。标识符中的字符也可以出现 下面是我尝试过的语法,但由于Lexer没有回溯,所以失败了,我不知道如何使它工作。 file : line* EOF; line : (line_one line_two* ) NEWLINE?; line_one : field+ LI

我们使用ANTLR解析复杂的文件结构,然后创建java对象来执行某些活动

到目前为止,文件中的每一行都以标识符开头。例如:
第1行…\n
第2行…\n
EOF

现在有了新的要求,线路的标识符,即线路1等,可以出现在线路的任何部分。标识符中的字符也可以出现

下面是我尝试过的语法,但由于Lexer没有回溯,所以失败了,我不知道如何使它工作。

file : line* EOF;

line : (line_one  line_two* ) NEWLINE?;

line_one : field+ LINE1_ID field* {
   System.out.println("got line_one:" + $line_one.text);
};

line_two  : field+ LINE2_ID field* {
   System.out.println("got line_two:" + $line_two.text);
};

field : (FIELD | SKIP_ID )+;

LINE1_ID : 'LINE1' ;

LINE2_ID  : 'LINE2' ;

SKIP_ID :   'L';

FIELD : FCHAR+;
fragment
FCHAR   :  ~('\r' | '\n' | 'L' );
NEWLINE: ('\r' '\n' | '\r' | '\n');
我不是Antlr或编写语法的专家,非常感谢您的指点或帮助。P.S.使用的Antlr版本是3.4,我们无法将其升级到4

正在使用的文件示例(固定长度格式):

每行的标识符由1001、1002等标记。1001是文件的头,1002标记组的开始,而1004标记组的结束。1003表示实际记录,1005表示文件结束。 行标识符位置的出现可能因行而异,但出现位置在一行中是固定的,即,如果同一行在CUST记录中多次出现,则位置固定为5(假设第一个字符位于位置0)

lexer的问题是,一旦识别出100,它就假定总是尝试与标题记录匹配,如果失败,它不会回溯,并且如果使用$line.text获取已使用的行,这些字符(即100)也会丢失

在上面的示例中,我使用数字来标识一行,但标识符可以是字母数字,并且有效字符是UTF-8的字符,而不仅仅是ASCII字符

上述语法的输入为:

 ABCDLINE1aaaaFGHA\n
 aaabbbBCLINE2XYZ\n
 LINELINELINE2PQR\n
 LIN QRSTLINE2ABC579\n
调用parser.file()时程序的输出:

got line_one:ABCDLINE1aaaaFGHA
line 2:8 mismatched input 'LINE2' expecting LINE1_ID
line 3:0 no viable alternative at character 'L'
line 2:16 mismatched input '\r\n' expecting LINE1_ID
line 3:4 no viable alternative at character 'L'
line 3:8 mismatched input 'LINE2' expecting LINE1_ID
line 4:0 no viable alternative at character 'L'
line 3:16 mismatched input '\r\n' expecting LINE1_ID
line 4:8 mismatched input 'LINE2' expecting LINE1_ID
line 4:19 mismatched input '\r\n' expecting LINE1_ID

感谢

@BartKiers,在上述语法中添加了示例、输入和输出。在我看来,您刚刚开始编写语法,而没有尝试熟悉ANTLR的基础知识。我建议你拿一份,从头开始。谢谢Bart,但你认为使用ANTLR3实现上述目标可行吗,还是我应该从其他方向着手处理?当然,但是您可能试图在解析器规则中加入太多的逻辑:通常最好稍微松散地匹配,然后遍历生成的AST以进行进一步验证。另外,请务必仔细阅读如何创建标记:ANTLR的lexer总是尽可能多地匹配标记。祝你好运
got line_one:ABCDLINE1aaaaFGHA
line 2:8 mismatched input 'LINE2' expecting LINE1_ID
line 3:0 no viable alternative at character 'L'
line 2:16 mismatched input '\r\n' expecting LINE1_ID
line 3:4 no viable alternative at character 'L'
line 3:8 mismatched input 'LINE2' expecting LINE1_ID
line 4:0 no viable alternative at character 'L'
line 3:16 mismatched input '\r\n' expecting LINE1_ID
line 4:8 mismatched input 'LINE2' expecting LINE1_ID
line 4:19 mismatched input '\r\n' expecting LINE1_ID