我正在使用ANTLRv3来解析看起来像这样的输入:
* this is an outline item at level 1
** item at level 2
*** item at level 3
* another item at level 1
* an item with *bold* text
一行开头的星号标记大纲项目的开头。星星也可以是项目文本的一部分(例如*bold*
)。
这是解析项目文本中不支持星号的大纲项目的语法:
outline_item: OUTLINE_ITEM_MARKER ITEM_TEXT;
OUTLINE_ITEM_MARKER: STAR_IN_COLUMN_ZERO STAR* (' '|'\t');
ITEM_TEXT: ('a'..'z'|'A'..'Z'|'0'..'9'|'\r'|'\n'|' '|'\t')+;
fragment STAR_IN_COLUMN_ZERO: {getCharPositionInLine()==0}? '*';
fragment STAR: {getCharPositionInLine()>0}? '*';
对于输入*** foo bar
,ANTLR生成以下分析树:
到目前为止,这是按预期工作的。现在我正在尝试将明星添加到项目文本的可能字符中,因此我将ITEM_TEXT
的词法分析器规则更改为以下内容:
ITEM_TEXT: ('a'..'z'|'A'..'Z'|'0'..'9'|'\r'|'\n'|' '|'\t'|STAR)+;
现在,对于相同的输入,将生成以下分析树:
这是ANTLRWorks中的输出:
input.txt line 1:0 rule STAR failed predicate: {getCharPositionInLine()>0}?
input.txt line 1:1 missing OUTLINE_ITEM_MARKER at '** foo bar'
由于OUTLINE_ITEM_MARKER
,MissingTokenException
似乎不匹配。语法有什么问题,我需要更改什么才能让星星成为ITEM_TEXT
的一部分?
答案 0 :(得分:2)
在fragment
中使用门控语义谓词 1 ,而不是验证语义谓词。
以下语法:
grammar Test;
outline_items
: outline_item+ EOF
;
outline_item
: OUTLINE_ITEM_MARKER ITEM_TEXT
;
OUTLINE_ITEM_MARKER
: STAR_IN_COLUMN_ZERO STAR* (' '|'\t')
;
ITEM_TEXT
: ('a'..'z'|'A'..'Z'|'0'..'9'|'\r'|'\n'|' '|'\t'|STAR)+
;
fragment STAR_IN_COLUMN_ZERO
: {getCharPositionInLine()==0}?=> '*'
;
fragment STAR
: {getCharPositionInLine()>0}?=> '*'
;
您的意见:
* this is an outline item at level 1
** item at level 2
*** item at level 3
* another item at level 1
* an item with *bold* text
然后将被解析为:
答案 1 :(得分:0)
您是否尝试过简化语法?
outline_item: OUTLINE_ITEM_MARKER ITEM_TEXT;
ITEM_TEXT:
(' '|'\t') (' '|'\t'|'a'..'z'|'A'..'Z'|'0'..'9'| STAR)+
;
OUTLINE_ITEM_MARKER:
STAR+
;
fragment STAR:
'*'
;
或者,如果您不需要将STAR保留为显式片段,并且您希望捕获项目文本中的所有字符,而不是子集:
outline_item: OUTLINE_ITEM_MARKER ITEM_TEXT;
ITEM_TEXT:
(' '|'\t') (~('\n'|'\r'))+
;
OUTLINE_ITEM_MARKER:
'*'+
;