我有一个相对简单的lex / flex文件,并且已经使用flex的调试标志运行它,以确保它正确地进行标记。不幸的是,我总是遇到两个问题之一 - flex生成的程序停止只是在几个令牌后静默放弃,或者我用来识别字符和字符串的规则没有被调用,默认规则而是被称为。
有人能指出我正确的方向吗?我已经附加了我的flex文件和示例输入/输出。
编辑:我发现生成的词法分析器在特定规则后停止:“cdr”。这更详细,但也更令人困惑。我发布了一个缩短修改后的lex文件。
/* lex file*/
%option noyywrap
%option nodefault
%{
enum tokens{
CDR,
CHARACTER,
SET
};
%}
%%
"cdr" { return CDR; }
"set" { return SET; }
[ \t\r\n] /*Nothing*/
[a-zA-Z0-9\\!@#$%^&*()\-_+=~`:;"'?<>,\.] { return CHARACTER; }
%%
示例输入:
set c cdra + cdr b + () ;
通过生成的解析器运行输入来完成输出:
--(end of buffer or a NUL)
--accepting rule at line 16 ("set")
--accepting rule at line 18 (" ")
--accepting rule at line 19 ("c")
--accepting rule at line 18 (" ")
--accepting rule at line 15 ("cdr")
有什么想法?生成的程序在输入的一半后放弃! (作为参考,我通过将文件内容重定向到生成的程序来进行输入。)
答案 0 :(得分:3)
当生成一个独立的词法分析器(也就是说,没有一个带有在bison / yacc中定义的标记的词法分析器时,你通常会在定义你的标记的文件顶部写一个枚举。但是,lex程序的主循环,包括默认生成的主循环,看起来像这样:
while( token = yylex() ){
...
这很好,直到你的词法分析器匹配枚举中首先出现的规则 - 在这个特定情况下CDR。由于枚举默认从零开始,因此会导致while循环结束。重新编号你的枚举 - 将解决问题。
enum tokens{
CDR = 1,
CHARACTER,
SET
};
短版本:当为词法分析器手动定义标记时,从1开始而不是0。
答案 1 :(得分:0)
此规则
[-+]?([0-9*\.?[0-9]+|[0-9]+\.)([Ee][-+]?[0-9]+)?
|
似乎在第0-9之后错过了一个结束括号,我添加了一个|在我认为应该是的地方下面。我无法猜测flex会如何回应。
我通常用于符号名称的规则是[a-zA-Z$_]
,这就像你的未加引号的字符串
除了我通常允许符号内的数字,只要符号不以数字开头。
[a-zA-Z$_]([a-zA-Z$_]|[0-9])*
字符只是一个简短的符号。我不认为它需要有自己的规则,但如果确实如此,那么你需要确保字符串规则至少需要2个字符。
[a-zA-Z$_]([a-zA-Z$_]|[0-9])+