我想为一个非常类似于以下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 );])
感谢。
答案 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_START
,SECTION_TAG_END
,GLOBAL_SECTION_TAG
,SHARE_NAME_SECTION_TAG
,PRINTER_SECTION_TAG
,NEW_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`