java - ANTLR3 C 目标错误生成 TreeParser : ( ASTTreeParser. stg 321:25:匿名模板有 0 个参数但映射到 1 个值)

标签 java c parsing antlr antlr3

我是 ANTLR 的新手,我正在尝试使用 C 目标在 ANTLR3 中创建一个规则评估器。我正在使用最新版本的 ANTLR3 (3.5.2) 和 Java 1.7.0.80 来生成代码。

我可以毫无问题地生成 Lexer 和 Parser,但是在尝试生成 TreeParser 时出现以下错误:

 : error 24 : template error: ASTTreeParser.stg 321:25: anonymous template has 0 arg(s) but mapped across 1 value(s)
 : error 24 : template error: ASTTreeParser.stg 323:25: anonymous template has 0 arg(s) but mapped across 1 value(s)

但是,当我将目标语言更改为 Java 时,没有发生任何错误并且代码(Java)已正确生成。

我的 Lexer/Parser 语法是:

grammar RuleParser;

options 
{ 
    language = C; 
    output = AST;
}


tokens 
{
    MB_TRUE = 'true';
    MB_FALSE = 'false';
    MB_AND = 'AND';
    MB_OR = 'OR';
    MB_LT = '<';
    MB_GT = '>';
    MB_LTEQ = '<=';
    MB_GTEQ = '>=';
    MB_EQ = '==';
    MB_NEQ = '!=';
    MB_LBRACK = '[';
    MB_RBRACK = ']';
    MB_LPAREN = '(';
    MB_RPAREN = ')';
    MB_LCURLY = '{';
    MB_RCURLY = '}';
    MB_COLON = ':';
    MB_SEMICOLON = ';';
    MB_COMA = ',';
    MB_OPTION = '|';
    MB_DOT = '.';
    MB_IN = 'IN';
    MB_STRING_SUFIX = '@';
    MB_CASE_SENSITIVE = 'CS';
    MB_CASE_INSENSITIVE = 'CI';
    MB_ENCODE_UNICODE = 'EU';       
    MB_ENCODE_ANSI = 'EA';
    MB_RULEDI = 'rule_di';
    MB_HEADER = 'header';
    MB_CONDITIONS = 'conditions';
    CONDITION = 'condition';
    RULE = 'rule';
    RULES = 'rules';
    MB_METADATA = 'metadata';
}

version 
    : INT MB_DOT! INT MB_DOT! INT
    ;

string
    : STRING^
    | STRING^ MB_STRING_SUFIX! MB_LBRACK! ((a=MB_CASE_INSENSITIVE | b=MB_CASE_SENSITIVE)? MB_OPTION!? (c=MB_ENCODE_UNICODE | d=MB_ENCODE_ANSI)?) MB_RBRACK!
    ;


// Rules definitions
rules 
    : rule+ -> ^(RULES rule+)
    ;

rule
    : MB_RULEDI MB_LCURLY header conditions MB_RCURLY -> ^(RULE header conditions)
;


header  
    : MB_HEADER MB_LCURLY header_block+ MB_RCURLY -> ^(MB_HEADER header_block+)
    ;


header_block
    : 'Id' MB_COLON INT MB_SEMICOLON -> ^(MB_METADATA 'Id' INT)
    | 'Version' MB_COLON version MB_SEMICOLON-> ^(MB_METADATA 'Version' version)
    | 'Author' MB_COLON STRING MB_SEMICOLON-> ^(MB_METADATA 'Author' STRING)
    | 'Date' MB_COLON DATE MB_SEMICOLON-> ^(MB_METADATA 'Date' DATE)
    | 'Brief' MB_COLON STRING MB_SEMICOLON-> ^(MB_METADATA 'Brief' STRING)
    ;

conditions
    : MB_CONDITIONS '{' conditions_block '}' -> ^(MB_CONDITIONS conditions_block)
    ;

conditions_block
    :   statement+ -> ^(CONDITION statement)+
    ;

statement
    :   expression MB_SEMICOLON -> expression 
    |   string MB_IN IDENTIFIER MB_SEMICOLON -> ^(MB_IN string IDENTIFIER)
    ;

expression
    :   andexpression;

andexpression : orexpression (MB_AND^ orexpression)*;

orexpression : term (MB_OR^ term)*;

term:   atom (( MB_LT | MB_GT | MB_LTEQ | MB_GTEQ | MB_EQ | MB_NEQ)^ atom)? | MB_LPAREN! expression MB_RPAREN!;

atom : IDENTIFIER | INT | string | MB_TRUE | MB_FALSE;


// Lexer rules
//-------------------------------------------------

DATE 
    : DATEDAY SEPARATOR (MONTH | DATEMONTH) SEPARATOR DATEYEAR
    ;

MONTH 
    : JAN | FEB | MAR | APR | MAY | JUN | JUL | AUG | SEP | OCT | NOV | DEC 
    ;

fragment JAN : ('J'|'j')('A'|'a')('N'|'n') ;
fragment FEB : ('F'|'f')('E'|'e')('B'|'b') ;
fragment MAR : ('M'|'m')('A'|'a')('R'|'r') ;
fragment APR : ('A'|'a')('P'|'p')('R'|'r') ;
fragment MAY : ('M'|'m')('A'|'a')('Y'|'y') ; 
fragment JUN : ('J'|'j')('U'|'u')('N'|'n') ;
fragment JUL : ('J'|'j')('U'|'u')('L'|'l') ;
fragment AUG : ('A'|'a')('U'|'u')('G'|'g') ;
fragment SEP : ('S'|'s')('E'|'e')('P'|'p') ; 
fragment OCT : ('O'|'o')('C'|'c')('T'|'t') ; 
fragment NOV : ('N'|'n')('O'|'o')('V'|'v') ;
fragment DEC : ('D'|'d')('E'|'e')('C'|'c') ;

SEPARATOR 
    : ('/'|'\\'|'-') 
    ;

fragment     
DATEMONTH
   :    ('0'..'1')?DIGIT
   ;

fragment
DATEDAY
    :   ('0'..'3')?DIGIT
    ;

fragment
DATEYEAR
     :  '2' DIGIT DIGIT DIGIT
     ;

fragment 
    ID  :   ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
    ;

IDENTIFIER: ID (MB_DOT ID)?;

COMMENT
    :   '//' ~('\n'|'\r')* '\r'? '\n' {$channel=HIDDEN;}
    |   '/*' ( options {greedy=false;} : . )* '*/' {$channel=HIDDEN;}
    ;

 WS  :   ( ' '
     | '\t'
     | '\r'
     | '\n'
     ) {$channel=HIDDEN;}
     ;

STRING
    :  '"' ( ESC_SEQ | ~('\\'|'"') )* '"'
    ;

CHAR:  '\'' ( ESC_SEQ | ~('\''|'\\') ) '\''
    ;

fragment
HEX_DIGIT 
    : ('0'..'9'|'a'..'f'|'A'..'F')  
    | '\t'
    | '\r'
    | '\n'
    ;

fragment
ESC_SEQ
    :   '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\')
    |   UNICODE_ESC
    |   OCTAL_ESC
    ;

fragment
OCTAL_ESC
    :   '\\' ('0'..'3') ('0'..'7') ('0'..'7')
    |   '\\' ('0'..'7') ('0'..'7')
    |   '\\' ('0'..'7')
    ;

fragment
UNICODE_ESC
    :   '\\' 'u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT
    ;

INT : DIGIT+;

fragment DIGIT : ('0'..'9'); 

我的树解析器语法:

tree grammar RuleParserTree;

options
{
    language = C;
    tokenVocab = RuleParser;
    output = AST;
    ASTLabelType = pANTLR3_BASE_TREE;

    //rewrite=true;
}


version 
    : INT INT INT
    ;

string
    : STRING
    | ^(STRING (a=MB_CASE_INSENSITIVE | b=MB_CASE_SENSITIVE)?  (c=MB_ENCODE_UNICODE | d=MB_ENCODE_ANSI)?)
    ;

// Rules definitions

rules 
    : ^(RULES rule+)
    ;

rule
    : ^(RULE header conditions)
    ;

 header 
    : ^(MB_HEADER header_block+)
    ;

header_block
    : ^(MB_METADATA 'Id' INT)
    | ^(MB_METADATA 'Version' version)
    | ^(MB_METADATA 'Author' STRING)
    | ^(MB_METADATA 'Date' DATE)
    | ^(MB_METADATA 'Brief' STRING)
    ;

conditions
    : ^(MB_CONDITIONS conditions_block)
    ;

conditions_block
    :   CONDITION statement+
    ;

statement
    :   expression  
    |   ^(MB_IN string IDENTIFIER)
    ;

expression
    :   ^(MB_AND expression expression)
    |   ^(MB_OR expression expression)
    |   ^(MB_LT expression expression)
    |   ^(MB_GT expression expression)
    |   ^(MB_LTEQ expression expression)
    |   ^(MB_GTEQ expression expression)
    |   ^(MB_EQ expression expression)
    |   ^(MB_NEQ expression expression)
    |   IDENTIFIER
    |   INT
    |   STRING
    |   MB_TRUE
    |   MB_FALSE
    ;

完整的日志转储:

ANTLR Parser Generator  Version 3.5.2
--------------------
 attempting LL(1) DFA (d=1) for 22:13: (a= MB_CASE_INSENSITIVE |b= MB_CASE_SENSITIVE )?
> LOOK(33)
< LOOK(33)=MB_CASE_INSENSITIVE
> LOOK(35)
< LOOK(35)=MB_CASE_SENSITIVE
> LOOK(37)
< LOOK(37)={UP, MB_ENCODE_ANSI..MB_ENCODE_UNICODE}
decision 1 is simple LL(1)
--------------------
attempting LL(1) DFA (d=2) for 22:60: (c= MB_ENCODE_UNICODE |d= MB_ENCODE_ANSI )?
> LOOK(41)
< LOOK(41)=MB_ENCODE_UNICODE
> LOOK(43)
< LOOK(43)=MB_ENCODE_ANSI
> LOOK(45)
< LOOK(45)=UP
decision 2 is simple LL(1)
--------------------
attempting LL(1) DFA (d=3) for 20:1: string : ( STRING | ^( STRING (a= MB_CASE_INSENSITIVE |b= MB_CASE_SENSITIVE )? (c= MB_ENCODE_UNICODE |d= MB_ENCODE_ANSI )? ) );
> LOOK(27)
< LOOK(27)=STRING
> LOOK(29)
< LOOK(29)=STRING
decision 3 not suitable for LL(1)-optimized DFA analysis
--------------------
building lookahead DFA (d=3) for 20:1: string : ( STRING | ^( STRING (a= MB_CASE_INSENSITIVE |b= MB_CASE_SENSITIVE )? (c= MB_ENCODE_UNICODE |d= MB_ENCODE_ANSI )? ) );
closure at string state 27|1 filling DFA state 0 with context [$]
closure at string state 29|2 filling DFA state 0 with context [$]
convert DFA state 0 (2 nfa states)
DFA state after reach 65 0:{27|1, 29|2}-STRING->1:{28|1, 30|2}
closure(1:{28|1, 30|2})
closure at string state 28|1 filling DFA state 1 with context [$]
closure at string state 51|1 filling DFA state 1 with context [$]
closure at string state 3|1 filling DFA state 1 with context [$]
closure at statement state 169|1 filling DFA state 1 with context [$]
resolveNonDeterminisms 1:{28|1, 30|2, 51|1, 3|1, 169|1}
convert DFA state 1 (5 nfa states)
DFA state after reach 2 1:{28|1, 30|2, 51|1, 3|1, 169|1}-DOWN->2:{32|2}
resolveNonDeterminisms 2:{32|2}
DFA state after reach 19 1:{28|1, 30|2, 51|1, 3|1, 169|1}-IDENTIFIER->3:{171|1}
resolveNonDeterminisms 3:{171|1}
cost: 4 states, 19 ms
--------------------
attempting LL(1) DFA (d=4) for ()+ loopback of 29:12: ( rule )+
> LOOK(58)
< LOOK(58)=RULE
> LOOK(62)
< LOOK(62)=UP
decision 4 is simple LL(1)
--------------------
attempting LL(1) DFA (d=5) for ()+ loopback of 40:16: ( header_block )+
> LOOK(81)
< LOOK(81)=MB_METADATA
> LOOK(85)
< LOOK(85)=UP
decision 5 is simple LL(1)
--------------------
attempting LL(1) DFA (d=6) for 44:1: header_block : ( ^( MB_METADATA 'Id' INT ) | ^( MB_METADATA 'Version' version ) | ^( MB_METADATA 'Author' STRING ) | ^( MB_METADATA 'Date' DATE ) | ^( MB_METADATA 'Brief' STRING ) );
> LOOK(89)
< LOOK(89)=MB_METADATA
> LOOK(99)
< LOOK(99)=MB_METADATA
> LOOK(109)
< LOOK(109)=MB_METADATA
> LOOK(119)
< LOOK(119)=MB_METADATA
> LOOK(129)
< LOOK(129)=MB_METADATA
decision 6 not suitable for LL(1)-optimized DFA analysis
--------------------
building lookahead DFA (d=6) for 44:1: header_block : ( ^( MB_METADATA 'Id' INT ) | ^( MB_METADATA 'Version' version ) | ^( MB_METADATA 'Author' STRING ) | ^( MB_METADATA 'Date' DATE ) | ^( MB_METADATA 'Brief' STRING ) );
closure at header_block state 89|1 filling DFA state 0 with context [$]
closure at header_block state 99|2 filling DFA state 0 with context [$]
closure at header_block state 109|3 filling DFA state 0 with context [$]
closure at header_block state 119|4 filling DFA state 0 with context [$]
closure at header_block state 129|5 filling DFA state 0 with context [$]
convert DFA state 0 (5 nfa states)
DFA state after reach 46 0:{89|1, 99|2, 109|3, 119|4, 129|5}-MB_METADATA->1:{90|1, 100|2, 110|3, 120|4, 130|5}
closure(1:{90|1, 100|2, 110|3, 120|4, 130|5})
resolveNonDeterminisms 1:{90|1, 100|2, 110|3, 120|4, 130|5}
convert DFA state 1 (5 nfa states)
DFA state after reach 2 1:{90|1, 100|2, 110|3, 120|4, 130|5}-DOWN->2:{92|1, 102|2, 112|3, 122|4, 132|5}
closure(2:{92|1, 102|2, 112|3, 122|4, 132|5})
resolveNonDeterminisms 2:{92|1, 102|2, 112|3, 122|4, 132|5}
convert DFA state 2 (5 nfa states)
DFA state after reach 71 2:{92|1, 102|2, 112|3, 122|4, 132|5}-'Id'->3:{94|1}
resolveNonDeterminisms 3:{94|1}
DFA state after reach 72 2:{92|1, 102|2, 112|3, 122|4, 132|5}-'Version'->4:{104|2}
resolveNonDeterminisms 4:{104|2}
DFA state after reach 68 2:{92|1, 102|2, 112|3, 122|4, 132|5}-'Author'->5:{114|3}
resolveNonDeterminisms 5:{114|3}
DFA state after reach 70 2:{92|1, 102|2, 112|3, 122|4, 132|5}-'Date'->6:{124|4}
resolveNonDeterminisms 6:{124|4}
DFA state after reach 69 2:{92|1, 102|2, 112|3, 122|4, 132|5}-'Brief'->7:{134|5}
resolveNonDeterminisms 7:{134|5}
cost: 8 states, 27 ms
--------------------
attempting LL(1) DFA (d=7) for ()+ loopback of 60:14: ( statement )+
> LOOK(156)
< LOOK(156)={IDENTIFIER..INT, MB_AND, MB_EQ..MB_GTEQ, MB_IN, MB_LT..MB_LTEQ, MB_NEQ, MB_OR, MB_TRUE, STRING}
> LOOK(160)
< LOOK(160)=UP
decision 7 is simple LL(1)
--------------------
attempting LL(1) DFA (d=8) for 64:1: statement : ( expression | ^( MB_IN string IDENTIFIER ) );
> LOOK(162)
< LOOK(162)={IDENTIFIER..INT, MB_AND, MB_EQ..MB_GTEQ, MB_LT..MB_LTEQ, MB_NEQ, MB_OR, MB_TRUE, STRING}
> LOOK(164)
< LOOK(164)=MB_IN
decision 8 is simple LL(1)
--------------------
attempting LL(1) DFA (d=9) for 70:1: expression : ( ^( MB_AND a= expression b= expression ) | ^( MB_OR a= expression b= expression ) | ^( MB_LT a= expression b= expression ) | ^( MB_GT a= expression b= expression ) | ^( MB_LTEQ a= expression b= expression ) | ^( MB_GTEQ a= expression b= expression ) | ^( MB_EQ a= expression b= expression ) | ^( MB_NEQ a= expression b= expression ) | IDENTIFIER | INT | STRING | MB_TRUE | MB_FALSE );
> LOOK(177)
< LOOK(177)=MB_AND
> LOOK(189)
< LOOK(189)=MB_OR
> LOOK(201)
< LOOK(201)=MB_LT
> LOOK(213)
< LOOK(213)=MB_GT
> LOOK(225)
< LOOK(225)=MB_LTEQ
> LOOK(237)
< LOOK(237)=MB_GTEQ
> LOOK(249)
< LOOK(249)=MB_EQ
> LOOK(261)
< LOOK(261)=MB_NEQ
> LOOK(273)
< LOOK(273)=IDENTIFIER
> LOOK(275)
< LOOK(275)=INT
> LOOK(277)
< LOOK(277)=STRING
> LOOK(279)
< LOOK(279)=MB_TRUE
> LOOK(281)
< LOOK(281)=MB_FALSE
decision 9 is simple LL(1)
: error 24 : template error: ASTTreeParser.stg 321:25: anonymous template has 0 arg(s) but mapped across 1 value(s)
: error 24 : template error: ASTTreeParser.stg 323:25: anonymous template has 0 arg(s) but mapped across 1 value(s)
> LOOK(32)
< LOOK(32)={UP, MB_CASE_INSENSITIVE..MB_CASE_SENSITIVE, MB_ENCODE_ANSI..MB_ENCODE_UNICODE}
> LOOK(57)
< LOOK(57)=RULE
> LOOK(69)
< LOOK(69)=MB_HEADER
> LOOK(80)
< LOOK(80)=MB_METADATA
> LOOK(92)
< LOOK(92)='Id'
> LOOK(102)
< LOOK(102)='Version'
> LOOK(112)
< LOOK(112)='Author'
> LOOK(122)
< LOOK(122)='Date'
> LOOK(132)
< LOOK(132)='Brief'
> LOOK(148)
< LOOK(148)=CONDITION
> LOOK(167)
< LOOK(167)=STRING
> LOOK(180)
< LOOK(180)={IDENTIFIER..INT, MB_AND, MB_EQ..MB_GTEQ, MB_LT..MB_LTEQ, MB_NEQ, MB_OR, MB_TRUE, STRING}
> LOOK(192)
< LOOK(192)={IDENTIFIER..INT, MB_AND, MB_EQ..MB_GTEQ, MB_LT..MB_LTEQ, MB_NEQ, MB_OR, MB_TRUE, STRING}
> LOOK(204)
< LOOK(204)={IDENTIFIER..INT, MB_AND, MB_EQ..MB_GTEQ, MB_LT..MB_LTEQ, MB_NEQ, MB_OR, MB_TRUE, STRING}
> LOOK(216)
< LOOK(216)={IDENTIFIER..INT, MB_AND, MB_EQ..MB_GTEQ, MB_LT..MB_LTEQ, MB_NEQ, MB_OR, MB_TRUE, STRING}
> LOOK(228)
< LOOK(228)={IDENTIFIER..INT, MB_AND, MB_EQ..MB_GTEQ, MB_LT..MB_LTEQ, MB_NEQ, MB_OR, MB_TRUE, STRING}
> LOOK(240)
< LOOK(240)={IDENTIFIER..INT, MB_AND, MB_EQ..MB_GTEQ, MB_LT..MB_LTEQ, MB_NEQ, MB_OR, MB_TRUE, STRING}
> LOOK(252)
< LOOK(252)={IDENTIFIER..INT, MB_AND, MB_EQ..MB_GTEQ, MB_LT..MB_LTEQ, MB_NEQ, MB_OR, MB_TRUE, STRING}
> LOOK(264)
< LOOK(264)={IDENTIFIER..INT, MB_AND, MB_EQ..MB_GTEQ, MB_LT..MB_LTEQ, MB_NEQ, MB_OR, MB_TRUE, STRING}

是我语法有问题还是C Generator Template有错误? 我看过一些类似错误的报告,例如 this one , 但总是与旧版本的 ANTLR 一起使用。

如果有任何帮助,我将不胜感激。 提前致谢。

更新 1:使用 bart-kiers 建议更新了 RuleParser.g 语法。

最佳答案

终于找到问题了。 RuleParserTree.g 文件中的 output = AST 选项被遗留下来。我删除了它,终于正确生成了代码。

关于java - ANTLR3 C 目标错误生成 TreeParser : ( ASTTreeParser. stg 321:25:匿名模板有 0 个参数但映射到 1 个值),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39870126/

相关文章:

iphone - 解析时发生变化的通知

Java - 在滚动文本中插入换行符

javascript - 我的调用 Spring Controller 失败

java - Spring Controller 是线程安全的吗?

c - 开关(){案例: } performance in C

C 程序命令提示符在 if 语句中关闭而不是在 main() 结束时暂停

c - 如何在 C 中创建字节数据包?

java - 如何在 JSP 中通过 URL 传递对象?

C++ substr,优化速度

javascript - 正则表达式在 HTML 中查找价格