2012-06-12 58 views
2

我有以下语法,我想匹配字符串“{name1,name2}”。我只想要至少有一个元素的名称/嵌入列表。但是我得到的错误:
线1:6的字符“”
线1:11人品没有可行的替代“}没有可行的替代”
线1:7不匹配输入“姓名”期待SIMPLE_VAR_TYPEAntlr空格标记错误

我希望空格等被忽略......另外有趣的是,输入“{name1,name2}”(在','之后没有空格)不会发生错误。 我的继承人gramar

grammar NusmvInput; 
options { 
    language = Java; 
} 
@header { 
    package secltlmc.grammar; 
} 
@lexer::header { 
    package secltlmc.grammar; 
} 
specification : 
    SIMPLE_VAR_TYPE EOF 
    ;  
INTEGER 
    : ('0'..'9')+ 
    ; 
SIMPLE_VAR_TYPE 
    : ('{' (NAME | INTEGER) (',' (NAME | INTEGER))* '}' ) 
    ; 
NAME 
    : ('A'..'Z' | 'a'..'z') ('a'..'z' | 'A'..'Z' | '0'..'9' | '_' | '$' | '#' | '-')* 
    ; 
WS 
    : (' ' | '\t' | '\n' | '\r')+ {$channel = HIDDEN;} 
    ; 

这是我的测试代码

package secltlmc; 
public class Main { 
    public static void main(String[] args) throws 
      IOException, RecognitionException { 
     CharStream stream = new ANTLRStringStream("{name1, name2}"); 
     NusmvInputLexer lexer = new NusmvInputLexer(stream); 
     CommonTokenStream tokenStream = new CommonTokenStream(lexer); 
     NusmvInputParser parser = new NusmvInputParser(tokenStream); 
     parser.specification(); 
    } 
} 

感谢您的帮助。

回答

2

问题是,您正试图用词法分析器解析SIMPLE_VAR_TYPE,即您试图将其设置为单个标记。在现实中,它看起来像你想要一个多令牌生产,因为你想通过WS将空白重新定向到隐藏通道。

您应该将SIMPLE_VAR_TYPE从词法分析规则更改为解析器规则,方法是将其首字母(或更好的整个名称)更改为小写。

specification : 
    simple_var_type EOF 
    ;  

simple_var_type 
    : ('{' (NAME | INTEGER) (',' (NAME | INTEGER))* '}' ) 
    ; 
+0

@HeinrichOdy我的理解是,词法规则仅明确使用其他词法分析器规则。解析器规则隐式使用所有词法分析器规则,因为解析器规则的级别较高。解析器为下一个标记调用词法分析器,词法分析器将“WS”传递给隐藏通道,然后移至下一个标记。你也可以明确地在词法规则中使用'WS'。 – dasblinkenlight

+0

Sry,删除我自己的评论...选择了你的答案,因为我明白在标记内部空白清除不能与隐藏标记一起工作,谢谢。 –

1

SIMPLE_VAR_TYPE把定义指定下面的表达式:

  • 打开{
  • 随后的NAME一个或INTEGER
  • 通过零个或更多的follwoed:
    • 逗号( ,),然后是之一或INTEGER
  • 后闭}

无处它允许空格输入(既不NAME也不INTEGER允许它要么),所以,当你提供得到一个错误,一个

尝试:

SIMPLE_VAR_TYPE 
: ('{' (NAME | INTEGER) (WS* ',' WS* (NAME | INTEGER))* '}' ) 
; 
+0

也许我也应该把WS添加到'{'WS * ... WS *'}',但我看到你在哪里,谢谢:) –