运行时 Antlr 4.5 解析器错误
Antlr 4.5 parser error during runtime
我正在为学习目的的编程语言构建简单的语法。
我 运行 陷入对我来说毫无意义的奇怪错误。
line 1:0 missing {'void', 'int', 'bool', 'string', 'union'} at 'void'
我正在使用来自该语法的预构建词法分析器和解析器:
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 () {}
错误消息表示包含值 'void' 的预期令牌类型与使用输入中的字符串 'void' 生成的实际令牌类型不匹配。查看您的词法分析器规则表明输入字符串 'void' 正在被 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() 方法通常就足够了。覆盖您的令牌子类以满足您自己的需要。
我正在为学习目的的编程语言构建简单的语法。
我 运行 陷入对我来说毫无意义的奇怪错误。
line 1:0 missing {'void', 'int', 'bool', 'string', 'union'} at 'void'
我正在使用来自该语法的预构建词法分析器和解析器:
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 () {}
错误消息表示包含值 'void' 的预期令牌类型与使用输入中的字符串 'void' 生成的实际令牌类型不匹配。查看您的词法分析器规则表明输入字符串 'void' 正在被 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() 方法通常就足够了。覆盖您的令牌子类以满足您自己的需要。