ANTLR区分DXF组代码和整数

时间:2014-05-22 11:38:49

标签: parsing antlr antlr4 dxf

我是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 ;  

2 个答案:

答案 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 ;

自然而然地出现在我的脑海中,而不是非常优雅。但奇怪的文件格式需要外来措施。

要稍微理清这一点,你是否可以修剪前导和尾随空格的行,然后进行词法和解析?