antlr语法的问题

时间:2011-06-05 06:13:41

标签: 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 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”。如何修改我的语法才能做到这一点?

很抱歉这个标题很糟糕,但我不知道如何用几句话来描述问题。任何帮助将不胜感激。

1 个答案:

答案 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个解析树:


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

解析树:

enter image description here

larger image


2

来源:

foreach
    where x = 1
        // main block is blank, do nothing
    when none
        print 'none'
endfor

解析树:

enter image description here


3

来源:

foreach
    where x = 1 when none = 2
        print 'none'
    // exceptional block is blank
endfor

解析树:

enter image description here