0

目标

我想减少(或消除)解析器中特定于 Java 的操作和谓词。也许这是不可能的,但我想在这里问一下,以防万一我错过了一些 ANTLR4 功能。(语言本身是第三方的,所以我无法控制。)

简化示例

我想使用的谓词大多是精确的(或者可能不区分大小写)字符串匹配。我可以制作大量并行的解析器规则集,但我宁愿不这样做,因为现实生活中的例子要复杂得多。

假设我得到了类似的东西:

isWidget(int) : "Whether it is a widget" : 4 ;
ownerFirstName(string) : "john" ;
ownerLastName(string) : "This is the last-name of the owner" : "doe" ;

我希望解析器查看默认值(行中的最后一项,例如4,"john""doe")并根据之前的类型(int), (string),来解析它(string)

main
    : stmt SEMIC (stmt SEMIC)* EOF 
    ;
stmt
    : propname=IDENTIFIER LPAREN datatype=IDENTIFIER RPAREN (COLON description=QUOTSTRING)? COLON df=defaultVal
    ;
defaultVal 
    : QUOTSTRING //TODO only this alt if datatype=string
    | NUM        //TODO only this alt if datatype=int
    ;

fragment Letter         :   'a'..'z' | 'A'..'Z' ;
fragment Digit          :   '0'..'9'                ;   
fragment Underscore     :   '_'                     ;
SEMIC   : ';' ;
COLON   : ':' ;
LPAREN  : '(' ;
RPAREN  : ')' ;
IDENTIFIER : (Letter|Underscore) (Letter|Underscore|Digit)*      ;
QUOTSTRING : '"' ~('"' |'\n' | '\r' | '\u2029' | '\u2028')* '"'  ;
NUM : Digit+ ;
WS : [ \t\n\r]+ -> skip ;

我知道我可以使用谓词和规则输入来做到这一点,但是我正在从与语言无关的语法跨越到带有嵌入式 Java 代码的语法。

4

1 回答 1

0

您的解析器应该可以毫无问题地处理以下内容:

isWidget(int) : "Whether it is a widget" : "foo" ;

换句话说,不要添加在这种情况下会失败的谓词,否则您将失去报告合理错误消息的能力。相反,如果默认值的类型与声明的类型不匹配,则在解析完成后使用特定于语言的侦听器或访问者实现来报告语义错误。

于 2013-09-22T22:28:50.143 回答