我正在编写一些SQL操作,并使用本文链接的语言定义:SQL lex yacc grammar
我看到,当我试图调用一个函数来检测insert语句的表名时,我在yytext上得到了以下标记。我的代码这样调用函数:
insert_statement:
INSERT INTO table opt_column_commalist values_or_query_spec
;
[..]
table:
NAME {setGlobalTablename(yytext);}
| NAME '.' NAME
;
[..]
当我使用这样的有效查询运行它时:
INSERT INTO users (uid,username,ocupation,age) VALUES (1,'john','tech','30');
我在yytext值中调用的函数中得到的标记是“(”。
我明白,要断定令牌是一个表,它必须读取下一个令牌(在本例中为“(”),但我不知道如何获取真正的表名(用户)。实际上,它不是前一个令牌,而是前两个,因为空间也被认为是一个令牌。
我不知道我是否理解错了什么,但我找不到取名字的方法。
最佳答案
不要在解析器中读取yytext
——因为您发现它包含的令牌可能是不可预测的,因为解析器可能会预先读取一个令牌,以决定何时移动或减少。
相反,您应该读取lexer中的yytext
(并且仅在lexer中),如果您需要解析器中的值,则应复制它。所以你最终得到了一个lexer规则,比如:
[a-zA-Z][a-zA-Z0-9]* { yylval.str = strdup(yytext); return NAME }
在解析器中:
%union {
char *str;
:
}
%token <str> NAME
:
%%
:
table: NAME { setGlobalTableName($1); }
| NAME '.' NAME ...