我是ANTLR的新手,我正在尝试用ANTLRv4为DXF files编写一个解析器。 DXF文件使用所谓的组代码来指定以下数据的类型。
某些DXF文件的示例摘录:
0
SECTION
2
HEADER
9
$ORTHOMODE
70
0
9
0
ENDSEC
例如,第一个0
表示在下一行中跟随一个字符串。组代码70
表示将跟随16Bit Integer,在示例中它是0
。
我现在的问题是如何区分组代码0
和整数0
。
在示例代码段中,似乎Integer值有一些特殊的缩进,但我在DXF参考中找不到任何相关内容。
到目前为止,我的想法是遵循ANTLR语法:
grammar SimpleDXF;
start : HEADER variable* ENDSEC ;
variable : varstart (groupcode NL value NL)+ ;
varstart : VAR ;
groupcode : INT ;
value : INT | ANYCHARSEQ ;
WS : [ \t]+ -> skip ;
NL : '\r'? '\n' ;
HEADER : '0' NL 'SECTION' NL '2' NL 'HEADER' NL ;
ENDSEC : '0' NL 'ENDSEC' NL ;
VAR : '9' NL VARNAME NL ;
VARNAME : '$' LETTER (LETTER | DIGIT)* NL ;
INT : DIGIT+ NL ;
ANYCHARSEQ : ANYCHAR+ NL ;
fragment ANYCHAR : [\u0021-\u00FF] ;
fragment LETTER : [A-Za-z_] ;
fragment DIGIT : [0-9] ;
但很明显,当尝试解析整数0
时,这会失败,因为词法分析器0
将其视为header
规则的原因。
所以现在我对如何解决我的问题毫无头绪。任何帮助都非常感谢。
编辑
更改了ANTLR语法以包含更多词法规则。现在的问题是词法分析器完全失败了。第一个输入字符是INT
令牌,而不是我想要的HEADER
令牌的一部分......原因是删除空格-> skip
将无法正常工作如果它在一个令牌内(见下面的例子):
对于输入A B
(两个字母之间的空格),该语法将起作用:
start : 'A' 'B' ;
WS : [ \t\r\n]+ -> skip ;
但是这个语法不起作用:
start : AB ;
AB : 'A' 'B' ;
WS : [ \t\r\n]+ -> skip ;
答案 0 :(得分:1)
我通过进行一些预处理来解决问题,其中每个组代码及其对应的值都在同一行上。正如@UweAllner建议的那样,预处理还消除了前导和尾随空格。预处理后问题的示例输入文件如下所示:
0 SECTION
2 HEADER
9 $ORTHOMODE
70 0
0 ENDSEC
像这样很容易区分组代码和简单整数,因为组代码总是在一行的开头,而整数在一行的末尾。以下示例语法解决了该问题:
grammar SimpleDXF;
start : HEADER variable* ENDSEC ;
variable : varstart groupcodevalue+ ;
varstart : VAR ;
groupcodevalue : GROUPCODE value ;
value : (INT | ANYCHARSEQ) NL ;
NL : '\r'? '\n' ;
HEADER : '0 SECTION' NL '2 HEADER' NL ;
ENDSEC : '0 ENDSEC' NL ;
VAR : '9 ' VARNAME NL ;
GROUPCODE : INT ' ' ;
VARNAME : '$' LETTER (LETTER | DIGIT)* ;
INT : '-'? DIGIT+ ;
ANYCHARSEQ : ANYCHAR+ ;
fragment ANYCHAR: [\u0021-\u00FF] ;
fragment LETTER : [A-Za-z_] ;
fragment DIGIT : [0-9] ;
答案 1 :(得分:0)
您缺少像
这样的规则group: groupcode NL value;
否则(如你所说),组码和值之间不可能有区别。 或者,如果一个组代码后跟几个值:
group: groupcode (NL value)+;
你应该将header和endsec定义为HEADER和ENDSEC,以允许词法分析器区分“只是一个数字”和“是一个序列的开始”。 同样可能是变量规则的开始(以及由固定句子组成的所有内容)。
编辑: 像
这样的东西HEADER : '0' WS* NL WS* 'SECTION' WS* NL WS* '2' WS* NL WS* 'HEADER' WS* NL ;
自然而然地出现在我的脑海中,而不是非常优雅。但奇怪的文件格式需要外来措施。
要稍微理清这一点,你是否可以修剪前导和尾随空格的行,然后进行词法和解析?