如何为samba配置文件编写一个antlr解析器

时间:2013-01-25 15:15:06

标签: file parsing configuration antlr samba

我想为一个非常类似于以下samba配置文件的文档创建一个解析器。它有很多部分,每个部分都有一个标题行,以[后跟一个关键字部分名称,例如global,share_name等,直到行尾。部分标题行后面是本节的参数。我们不知道一节的结尾,直到我们到达另一节新行的开头[..,我怎么能为这种文档写一条规则?我找到的所有antlr示例都确切地知道何时开始一个部分以及何时结束一个部分。非常感谢!

[global]
    netbios name = NETBIOS_NAME
    workgroup = WORKGROUP
    security = user
[SHARE_NAME]
    comment = COMMENT
    force create mode = 0770
    locking = yes
[printers]
    comment = COMMENT
    path = /var/spool/samba
    browseable = No

这是我的语法:

grammar SambaConfiguration;

file    :   global_section
    share_name_section
    printer_section
    EOF
;

global_section 
    :   SECTION_TAG_START GLOBAL_SECTION_TAG (.)* SECTION_TAG_END NEW_LINE
    (~SECTION_TAG_START (.)* NEW_LINE)*
    ;

share_name_section 
    :   SECTION_TAG_START SHARE_NAME_SECTION_TAG (.)*  SECTION_TAG_END NEW_LINE
    ((~SECTION_TAG_START) (.)* NEW_LINE)*
    ;

printer_section
    :   SECTION_TAG_START PRINTER_SECTION_TAG (.)* SECTION_TAG_END NEW_LINE
    ((~SECTION_TAG_START) (.)* NEW_LINE)*
    ;

SECTION_TAG_START 
    :   '['
    ;

SECTION_TAG_END
    :   ']'
    ;

GLOBAL_SECTION_TAG
    :   'global' 
    ;

SHARE_NAME_SECTION_TAG 
    :   'SHARE_NAME' 
    ;

PRINTER_SECTION_TAG 
    :   'printer'
    ;   


NEW_LINE :
    '\r' ? '\n' | '\r'
    ;
WHITE_SPACE 
    :   ' ' | '\t'
    ;

不知何故,它无法正常工作。在Antlrworks中运行时,它给出了以下异常:

  

问题匹配令牌在12:19 NoViableAltException('o'@ [1:1:令牌   :(SECTION_TAG_START | SECTION_TAG_END | GLOBAL_SECTION_TAG |   SHARE_NAME_SECTION_TAG | PRINTER_SECTION_TAG | NEW_LINE | WHITE_SPACE   );])

感谢。

1 个答案:

答案 0 :(得分:1)

错误消息:

  

问题匹配令牌在12:19 NoViableAltException('o'@ [1:1:Tokens:(SECTION_TAG_START | SECTION_TAG_END | GLOBAL_SECTION_TAG | SHARE_NAME_SECTION_TAG | PRINTER_SECTION_TAG | NEW_LINE | WHITE_SPACE);])

表示ANTLR遇到一个字符'o',它无法为其创建令牌。您可能认为它将与解析器规则中的.匹配,但事实并非如此。在解析器规则内部,.匹配任何令牌,而仅在词法分析器规则内它匹配任何字符。

您的词法分析器仅创建以下令牌:SECTION_TAG_STARTSECTION_TAG_ENDGLOBAL_SECTION_TAGSHARE_NAME_SECTION_TAGPRINTER_SECTION_TAGNEW_LINE和{{1 }}。因此,解析器规则中的WHITE_SPACE匹配任何这些令牌,仅此而已。

除非你这样做是为了学习ANTLR,否则我会毫不犹豫地使用ANTLR来完成这项任务。使用一些内置的字符串操作并逐行读取输入,可以更轻松地完成此任务。

使用ANTLR,你可以做类似的事情:

.

解析您的示例输入会将以下内容打印到您的控制台:

name=global
  key=`netbios name`, value=`NETBIOS_NAME`
  key=`workgroup`, value=`WORKGROUP`
  key=`security`, value=`user`
name=SHARE_NAME
  key=`comment`, value=`COMMENT`
  key=`force create mode`, value=`0770`
  key=`locking`, value=`yes`
name=printers
  key=`comment`, value=`COMMENT`
  key=`path`, value=`/var/spool/samba`
  key=`browseable`, value=`No`