1

我有一个相对简单的 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")

有什么想法吗?生成的程序输入一半就放弃了!(作为参考,我通过将文件的内容重定向到生成的程序来进行输入)。

4

2 回答 2

3

当生成一个独立的词法分析器时(也就是说,不是具有在 bison/yacc 中定义的标记的词法分析器,您通常会在定义标记的文件顶部编写一个枚举。但是,lex 程序的主循环,包括主循环默认生成的循环,看起来像这样:

while( token = yylex() ){
    ...

这很好,直到您的词法分析器与枚举中首先出现的规则匹配 - 在这种特定情况下是 CDR。由于枚举默认从零开始,这会导致 while 循环结束。重新编号您的枚举 - 将解决问题。

enum tokens{
            CDR = 1,
            CHARACTER,
            SET
    };

简短版本:为词法分析器手动定义标记时,从 1 而不是 0 开始。

于 2010-02-14T17:10:38.113 回答
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])+
于 2010-02-14T06:26:51.383 回答