我正在构建简单的语法来编写laguange用于学习目的。
我遇到了一个对我毫无意义的奇怪错误。
line 1:0 missing {'void', 'int', 'bool', 'string', 'union'} at 'void'
我正在使用这种语法的prebuild lexer和parser:
grammar ProgrammingLanguage;
function_definition
: type_specifier IDENTIFIER '(' parameter_list_opt ')' compound_statement
;
type_specifier
: VOID
| INT
| BOOL
| STRING
| UNION
;
compound_statement
: '{' declaration_list statement_list '}'
;
statement_list
: statement
| statement statement_list
|
;
statement
: compound_statement
| selection_statement
| while_statement
| jump_statement
| expression_statement
| comment_statement
;
comment_statement
: COMMENT_START COMMENT
;
selection_statement
: IF '(' expression ')' compound_statement
| IF '(' expression ')' compound_statement ELSE compound_statement
| SWITCH '(' expression ')' compound_statement
;
expression_statement
: ';'
| expression ';'
;
jump_statement
: BREAK ';'
| CONTINUE ';'
;
while_statement
: WHILE '(' expression ')' compound_statement
;
primary_expression
: IDENTIFIER
| CONSTANT
| '(' expression ')'
| IDENTIFIER '(' primary_expression_list ')'
;
primary_expression_list
: primary_expression
| primary_expression primary_expression_list
|
;
expression
: logical_or_expression
| additive_expression
;
logical_or_expression
: logical_and_expression
| logical_or_expression '||' logical_and_expression
;
logical_and_expression
: compare_expression
| logical_and_expression '&&' compare_expression
;
compare_expression
: primary_expression compare_op primary_expression
| primary_expression
;
compare_op
: '<'
| '>'
| '=='
| '!='
| '<='
| '>='
;
additive_expression
: multiplicative_expression
| additive_expression '+' multiplicative_expression
| additive_expression '-' multiplicative_expression
;
multiplicative_expression
: primary_expression
| multiplicative_expression '*' primary_expression
| multiplicative_expression '/' primary_expression
| multiplicative_expression '%' primary_expression
;
assignment_expression
: IDENTIFIER '=' expression
;
id_list
: IDENTIFIER
| IDENTIFIER ',' id_list
;
declaration
: type_specifier id_list ';'
;
parameter_list_opt
: parameter_list
|
;
parameter_list
: type_specifier IDENTIFIER
| type_specifier IDENTIFIER ',' parameter_list
;
declaration_list
: declaration
| declaration declaration_list
|
;
/**------------------------------------------------------------------
* LEXER RULES
*------------------------------------------------------------------
*/
WHILE : 'while' ;
BREAK : 'break' ;
CONTINUE : 'continue' ;
SWITCH : 'switch' ;
IF : 'if' ;
ELSE : 'else' ;
COMMENT_START : '//' ;
IDENTIFIER : ('a'..'z'|'A'..'Z')('0'..'9'|'a'..'z'|'A'..'Z')*;
CONSTANT : FALSE|TRUE|STRING_VALUE|INT_VALUE;
STRING_VALUE : '"'COMMENT'"';
COMMENT : ('0'..'9'|'a'..'z'|'A'..'Z')*;
INT_VALUE : ('0'..'9')+;
FALSE : 'false';
TRUE : 'true';
VOID : 'void';
INT : 'int';
BOOL : 'bool';
STRING : 'string';
UNION : 'union';
WS : (' '|'\t'|'\n'|'\r')+ -> skip;
我正在解析这个java代码:
import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.tree.ParseTreeWalker;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException {
ProgrammingLanguageLexer lexer = new ProgrammingLanguageLexer(new ANTLRFileStream("input.txt"));
ProgrammingLanguageParser parser = new ProgrammingLanguageParser(new CommonTokenStream(lexer));
ParseTree tree = parser.function_definition();
ParseTreeWalker.DEFAULT.walk(new ProgrammingLanguageBaseListener(), tree);
}
}
最后是字符串,我正在尝试解析:
void power () {}
答案 0 :(得分:3)
错误消息表示包含值&#39; void&#39;的预期令牌类型。与使用字符串生成的实际令牌类型不匹配&#39; void&#39;从输入。查看您的词法分析器规则表明输入字符串&#39; void&#39;正在被IDENTIFIER规则使用,产生IDENTIFIER类型的令牌,而不是VOID。
通常,匹配最长输入字符串的词法分析器规则获胜。对于具有相同匹配长度的两个(或更多)规则,第一个列出的胜利。将所有关键字规则移到IDENTIFIER规则之上。
一个有用的单元测试表将转储lex标记并显示匹配的实际标记类型。类似的东西:
CommonTokenStream tokens = ...
tokens.fill();
StringBuilder sb = new StringBuilder();
for (Token token : tokens.getTokens()) {
sb.append(((YourCustomTokenType) token).toString());
}
System.out.print(sb.toString());
Token.toString()方法通常足够好。覆盖您的令牌子类以满足您自己的需要。