警告,使用 flex 和 bison 的词法分析器无法匹配规则
warning, rule cannot be matched for lexer using flex & bison
我正在使用 flex 和 bison 为一种编程语言创建词法分析器和语法分析器,但是当我编译我的程序时我收到警告
规则无法匹配
对于我的 lex.l,特别是对于我的词法分析器(lex.l 文件)中的“var”、“function”、“if”、“else”和“while”标记。
我附上了我的 lex.l 和 parse.y 文件,它们分别代表我的词法分析器和解析器。任何见解将不胜感激
lex.l
%{
#include "util.h"
#include "node.h"
#include "parse.tab.h"
void yyerror(const char *fmt, ...);
int create_token(int tag, const char *lexeme);
// global variable pointing to string containing name of input file
//var a b
//a + b
char *g_srcfile;
%}
%option yylineno
%option noyywrap
%%
[A-Za-z][A-Za-z0-9]* { return create_token(TOK_IDENTIFIER, yytext); }
"-"?(0|[1-9][0-9]*)("."[0-9]*)?((e|E)("+"|"-")?[0-9]+)? {
return create_token(TOK_NUMBER, yytext); }
"(" { return create_token(TOK_LPARENTHESIS, yytext); }
")" { return create_token(TOK_RPARENTHESIS, yytext); }
"{" { return create_token(TOK_LCURLY_BRACE, yytext); }
"}" { return create_token(TOK_RCURLY_BRACE, yytext); }
";" { return create_token(TOK_COLON, yytext); }
"," { return create_token(TOK_COMMA, yytext); }
"+" { return create_token(TOK_ADD, yytext); }
"-" { return create_token(TOK_SUBTRACT, yytext); }
"*" { return create_token(TOK_MULTIPLY, yytext); }
"/" { return create_token(TOK_DIVIDE, yytext); }
"==" { return create_token(TOK_CHECK_EQUAL, yytext); }
"!=" { return create_token(TOK_NOT_EQUAL, yytext); }
"<" { return create_token(TOK_LESS, yytext); }
">" { return create_token(TOK_GREATER, yytext); }
"<=" { return create_token(TOK_LESS_EQUAL, yytext); }
">=" { return create_token(TOK_GREATER_EQUAL, yytext); }
"&&" { return create_token(TOK_AND, yytext); }
"||" { return create_token(TOK_OR, yytext); }
"=" { return create_token(TOK_EQUAL, yytext); }
"var" { return create_token(TOK_VAR, yytext); }
"function" { return create_token(TOK_FUNCTION, yytext); }
"if" { return create_token(TOK_IF, yytext); }
"else" { return create_token(TOK_ELSE, yytext); }
"while" { return create_token(TOK_WHILE, yytext); }
"//" { return create_token(TOK_COMMENT, yytext); }
[ \t\r\n\v]+ { /* ignore whitespace */ }
. { yyerror("Unknown character: %c\n", yytext[0]); }
%%
void lexer_set_source_file(const char *filename) {
g_srcfile = xstrdup(filename);
}
int create_token(int tag, const char *lexeme) {
yylval.node = node_alloc_str_copy(tag, yytext);
return tag;
}
这是我的解析器
parse.y
%{
#include <stdio.h>
#include <stdarg.h>
#include "util.h"
#include "node.h"
#include "grammar_symbols.h"
int yylex(void);
void yyerror(const char *fmt, ...);
// global variable to point to the root of the parse tree
struct Node *g_translation_unit;
struct Node *g_expression;
struct Node *g_definition;
struct Node *g_parse_tree;
%}
%union {
struct Node *node;
}
/* TODO: define terminal and nonterminal symbols */
%token<node> TOK_IDENTIFIER
%type<node> translation_unit
%type<node> definition
%type<node> expression variable_declaration_statement if_statement
%type<node> if_else_statement while_statement unary_expression primary_expression
%type<node> parenthesized_subexpression function_call opt_argument_list
%type<node> statement opt_parameter_list statement_list function
%type<node> expression_statement
%token<node> TOK_LPARENTHESIS TOK_RPARENTHESIS TOK_LCURLY_BRACE TOK_RCURLY_BRACE
%token<node> TOK_COLON TOK_COMMA
%token<node> TOK_NUMBER TOK_STRING_LITERAL
%token<node> TOK_ADD TOK_SUBTRACT TOK_MULTIPLY TOK_DIVIDE
%token<node> TOK_CHECK_EQUAL TOK_NOT_EQUAL TOK_LESS TOK_GREATER TOK_LESS_EQUAL TOK_GREATER_EQUAL TOK_AND TOK_OR TOK_EQUAL
%token<node> TOK_VAR TOK_FUNCTION TOK_IF TOK_ELSE TOK_WHILE
%token<node> TOK_COMMENT
%%
/* TODO: add actual grammar rules */
translation_unit
: definition { g_translation_unit = $$ = node_build1(NODE_translation_unit, ); }
;
definition
: statement { g_definition = $$ = node_build1(NODE_definition, ); }
| function { $$ = g_definition = node_build1(NODE_definition, ); }
;
... deleted not related code
%%
void yyerror(const char *fmt, ...) {
extern char *g_srcfile;
extern int yylineno, g_col;
va_list args;
va_start(args, fmt);
int error_col = 1; // TODO: determine column number
fprintf(stderr, "%s:%d:%d: Error: ", g_srcfile, yylineno, error_col);
verr_fatal(fmt, args);
va_end(args);
}
关键字无法匹配,因为您的标识符规则在您的文件中排在第一位。每个关键字也是一个有效的标识符;您需要关键字规则优先,如果它出现得早,它就会优先。
我正在使用 flex 和 bison 为一种编程语言创建词法分析器和语法分析器,但是当我编译我的程序时我收到警告
规则无法匹配
对于我的 lex.l,特别是对于我的词法分析器(lex.l 文件)中的“var”、“function”、“if”、“else”和“while”标记。
我附上了我的 lex.l 和 parse.y 文件,它们分别代表我的词法分析器和解析器。任何见解将不胜感激
lex.l
%{
#include "util.h"
#include "node.h"
#include "parse.tab.h"
void yyerror(const char *fmt, ...);
int create_token(int tag, const char *lexeme);
// global variable pointing to string containing name of input file
//var a b
//a + b
char *g_srcfile;
%}
%option yylineno
%option noyywrap
%%
[A-Za-z][A-Za-z0-9]* { return create_token(TOK_IDENTIFIER, yytext); }
"-"?(0|[1-9][0-9]*)("."[0-9]*)?((e|E)("+"|"-")?[0-9]+)? {
return create_token(TOK_NUMBER, yytext); }
"(" { return create_token(TOK_LPARENTHESIS, yytext); }
")" { return create_token(TOK_RPARENTHESIS, yytext); }
"{" { return create_token(TOK_LCURLY_BRACE, yytext); }
"}" { return create_token(TOK_RCURLY_BRACE, yytext); }
";" { return create_token(TOK_COLON, yytext); }
"," { return create_token(TOK_COMMA, yytext); }
"+" { return create_token(TOK_ADD, yytext); }
"-" { return create_token(TOK_SUBTRACT, yytext); }
"*" { return create_token(TOK_MULTIPLY, yytext); }
"/" { return create_token(TOK_DIVIDE, yytext); }
"==" { return create_token(TOK_CHECK_EQUAL, yytext); }
"!=" { return create_token(TOK_NOT_EQUAL, yytext); }
"<" { return create_token(TOK_LESS, yytext); }
">" { return create_token(TOK_GREATER, yytext); }
"<=" { return create_token(TOK_LESS_EQUAL, yytext); }
">=" { return create_token(TOK_GREATER_EQUAL, yytext); }
"&&" { return create_token(TOK_AND, yytext); }
"||" { return create_token(TOK_OR, yytext); }
"=" { return create_token(TOK_EQUAL, yytext); }
"var" { return create_token(TOK_VAR, yytext); }
"function" { return create_token(TOK_FUNCTION, yytext); }
"if" { return create_token(TOK_IF, yytext); }
"else" { return create_token(TOK_ELSE, yytext); }
"while" { return create_token(TOK_WHILE, yytext); }
"//" { return create_token(TOK_COMMENT, yytext); }
[ \t\r\n\v]+ { /* ignore whitespace */ }
. { yyerror("Unknown character: %c\n", yytext[0]); }
%%
void lexer_set_source_file(const char *filename) {
g_srcfile = xstrdup(filename);
}
int create_token(int tag, const char *lexeme) {
yylval.node = node_alloc_str_copy(tag, yytext);
return tag;
}
这是我的解析器
parse.y
%{
#include <stdio.h>
#include <stdarg.h>
#include "util.h"
#include "node.h"
#include "grammar_symbols.h"
int yylex(void);
void yyerror(const char *fmt, ...);
// global variable to point to the root of the parse tree
struct Node *g_translation_unit;
struct Node *g_expression;
struct Node *g_definition;
struct Node *g_parse_tree;
%}
%union {
struct Node *node;
}
/* TODO: define terminal and nonterminal symbols */
%token<node> TOK_IDENTIFIER
%type<node> translation_unit
%type<node> definition
%type<node> expression variable_declaration_statement if_statement
%type<node> if_else_statement while_statement unary_expression primary_expression
%type<node> parenthesized_subexpression function_call opt_argument_list
%type<node> statement opt_parameter_list statement_list function
%type<node> expression_statement
%token<node> TOK_LPARENTHESIS TOK_RPARENTHESIS TOK_LCURLY_BRACE TOK_RCURLY_BRACE
%token<node> TOK_COLON TOK_COMMA
%token<node> TOK_NUMBER TOK_STRING_LITERAL
%token<node> TOK_ADD TOK_SUBTRACT TOK_MULTIPLY TOK_DIVIDE
%token<node> TOK_CHECK_EQUAL TOK_NOT_EQUAL TOK_LESS TOK_GREATER TOK_LESS_EQUAL TOK_GREATER_EQUAL TOK_AND TOK_OR TOK_EQUAL
%token<node> TOK_VAR TOK_FUNCTION TOK_IF TOK_ELSE TOK_WHILE
%token<node> TOK_COMMENT
%%
/* TODO: add actual grammar rules */
translation_unit
: definition { g_translation_unit = $$ = node_build1(NODE_translation_unit, ); }
;
definition
: statement { g_definition = $$ = node_build1(NODE_definition, ); }
| function { $$ = g_definition = node_build1(NODE_definition, ); }
;
... deleted not related code
%%
void yyerror(const char *fmt, ...) {
extern char *g_srcfile;
extern int yylineno, g_col;
va_list args;
va_start(args, fmt);
int error_col = 1; // TODO: determine column number
fprintf(stderr, "%s:%d:%d: Error: ", g_srcfile, yylineno, error_col);
verr_fatal(fmt, args);
va_end(args);
}
关键字无法匹配,因为您的标识符规则在您的文件中排在第一位。每个关键字也是一个有效的标识符;您需要关键字规则优先,如果它出现得早,它就会优先。