antlr语法的问题
我试图找出以下语法的语法antlr语法的问题,antlr,antlr3,Antlr,Antlr3,我试图找出以下语法的语法 foreach where x = 1 when some_variable = true where x = 2 when some_variable = false where y = 0 print z // Main block when none // optional print 'not found' // Exception b
foreach
where x = 1 when some_variable = true
where x = 2 when some_variable = false
where y = 0
print z // Main block
when none // optional
print 'not found' // Exception block
endfor
我的语法看起来像:
foreach_stmt : 'for' 'each' where_opt* blockstmt* whennone_opt? 'endfor'
;
where_opt : 'where' cond_clause
;
cond_clause : test when_opt*
;
when_opt : 'when' test
;
whennone_opt : 'when' 'none' blockstmt*
;
test : or_test
;
// further rules omitted
但是当主块为空时,例如
foreach
where x = 1
// main block is blank, do nothing
when none
print 'none'
endfor
在这种情况下,我的语法认为“when none”是“where x=1”的第二个从句,这不是我所期望的
也考虑以下情况:
foreach
where x = 1 when none = 2
print 'none'
// exceptional block is blank
endfor
其中“none”可以是一个变量,“none=2”应该匹配“test”规则,因此它是“Where…when…”的一部分
但是,当表达式语句中没有“none”时,我希望“when none”与“foreach”匹配,而不是前面的“where”。我如何修改语法才能做到这一点
对不起,这个标题很烂,但我不知道如何用几句话来描述这个问题。任何帮助都将不胜感激。解析器由以下ANTLR语法生成:
grammar Genexus;
parse
: foreach_stmt* EOF
;
foreach_stmt
: 'foreach' where_opt* blockstmt* whennone_opt? 'endfor'
;
where_opt
: 'where' cond_clause
;
cond_clause
: test when_opt*
;
when_opt
: 'when' test
;
whennone_opt
: 'when' 'none' blockstmt*
;
test
: identifier '=' atom
;
identifier
: 'none'
| Identifier
;
blockstmt
: 'print' atom
;
atom
: Boolean
| Number
| StringLiteral
| Identifier
;
Number
: '0'..'9'+
;
Boolean
: 'true'
| 'false'
;
Identifier
: ('a'..'z' | 'A'..'Z' | '_')+
;
StringLiteral
: '\'' ~'\''* '\''
;
Ignore
: (' ' | '\t' | '\r' | '\n') {skip();}
| '//' ~('\r' | '\n')* {skip();}
| '/*' .* '*/' {skip();}
;
根据示例生成以下3个解析树:
1. 资料来源:
foreach
where x = 1 when some_variable = true
where x = 2 when some_variable = false
where y = 0
print z // Main block
when none // optional
print 'not found' // Exception block
endfor
foreach
where x = 1
// main block is blank, do nothing
when none
print 'none'
endfor
foreach
where x = 1 when none = 2
print 'none'
// exceptional block is blank
endfor
解析树:
2. 资料来源:
foreach
where x = 1 when some_variable = true
where x = 2 when some_variable = false
where y = 0
print z // Main block
when none // optional
print 'not found' // Exception block
endfor
foreach
where x = 1
// main block is blank, do nothing
when none
print 'none'
endfor
foreach
where x = 1 when none = 2
print 'none'
// exceptional block is blank
endfor
解析树:
3. 资料来源:
foreach
where x = 1 when some_variable = true
where x = 2 when some_variable = false
where y = 0
print z // Main block
when none // optional
print 'not found' // Exception block
endfor
foreach
where x = 1
// main block is blank, do nothing
when none
print 'none'
endfor
foreach
where x = 1 when none = 2
print 'none'
// exceptional block is blank
endfor
解析树:
为什么允许
none
同时作为关键字和标识符?你让自己很难解析这些源。我还想知道blockstmt可能是什么:你能发布你的全部语法吗?@Bart我没有设计那种语言(实际上它是genexus的脚本语言,一种神秘的工具),所以我不得不接受其中所有棘手的部分。虽然理论上,none
是一个有效的变量名,但我认为忽略这个情况也是可以接受的,因为我想人们几乎不会做这样疯狂的事情。。。整个语法有点大,大多数规则与此问题无关。“我会尽量写一个简单的语法。”肖恩,啊,我明白了。您是自己提取这些规则的,还是根据genexus制造商的正式(BNF)规范创建的?如果是后者,你能发布一个到规范的链接吗?谢谢@巴特:有一个维基,在那里可以找到大多数BNF。基本上,我是根据这些信息提取规则的。但它们并不完整,还有一些未记录的语法,这是我在解析几个实际项目时遇到的。单击该链接时,我没有看到BNF规范。在我看来,你发布的更多的是函数/方法列表。更像是一个API。通过使用搜索,我遇到了一个没有答案的问题,所以我猜这种语言是专有的,如果不熟悉这种语言,就很难为它编写正确的语法。因为我对此一无所知,我想我帮不了什么忙。非常感谢。我意识到问题可能在于blockstmt部分,我正试图弄清楚这一部分,但有许多复杂的规则使得它很难在AntlWorks中顺利运行。语法在很大程度上依赖于回溯,我也在尝试删除回溯。我会做一个更清晰的版本,然后编辑这个问题。很抱歉,我的回复太晚了,被其他作品抓住了。@Shaung,当你的语法中只有一个谓词时,不要依赖ANTLRWorks的解释器。您可能看到的解析树很可能不是由语法生成的解析器导致的正确树。