我正在试图找出以下语法的语法。
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
在这种情况下,我的语法认为“当没有”是对“x = 1”的cond_clause,这不是我所期待的。
还要考虑以下情况:
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”。如何修改我的语法才能做到这一点?
很抱歉这个标题很糟糕,但我不知道如何用几句话来描述问题。任何帮助将不胜感激。
答案 0 :(得分:2)
从以下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个解析树:
来源:
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
解析树: