加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

解析 – 如何使lex / flex识别不被空格分隔的标记?

发布时间:2020-12-15 02:10:26 所属栏目:百科 来源:网络整理
导读:我正在学习编译器构建课程,目前的任务是为我们正在实现的语言编写词法分析器.我无法弄清楚如何满足词法分析器必须识别连接标记的要求.也就是说,令牌没有被空格分隔.例如:字符串39if应该被识别为数字39和关键字if.同时,词法分析器在遇到无效输入时也必须退出
我正在学习编译器构建课程,目前的任务是为我们正在实现的语言编写词法分析器.我无法弄清楚如何满足词法分析器必须识别连接标记的要求.也就是说,令牌没有被空格分隔.例如:字符串39if应该被识别为数字39和关键字if.同时,词法分析器在遇到无效输入时也必须退出(1).

我的代码的简化版本:

%{
#include <stdio.h>
%}

%option main warn debug

%%

if      |
then    |
else    printf("keyword: %sn",yytext);

[[:digit:]]+    printf("number: %sn",yytext);

[[:alpha:]][[:alnum:]]*     printf("identifier: %sn",yytext);

[[:space:]]+    // skip whitespace
[[:^space:]]+   { printf("ERROR: %sn",yytext); exit(1); }

%%

当我运行此(或我的完整版本),并将输入39if传递给它时,错误规则匹配,输出为ERROR:39if,当我希望它为:

number: 39
keyword: if

(即,如果输入则输入39,就像我输入的那样.)

Going by the manual,我有一个预感,原因是错误规则匹配的数字和关键字规则的输入时间更长,而flex会更喜欢它.那就是说,我不知道如何解决这种情况.编写一个拒绝所有非错误输入的显式正则表达似乎是不可行的,我不知道如何为了处理词法错误而编写“全能”规则.

更新:我想我可以制定全能规则. {exit(1);但是我希望得到一些比“我在第1行感到困惑”更好的调试输出.

解决方法

你应该只将一个“任意”角色作为后备来匹配,这是对的.获取解析所在行的信息的“标准”方法是使用–bison-bridge选项,但这可能有点痛苦,特别是如果你不使用野牛.还有很多其他的方法 – 例如,在手册中查找指定自己的i / o函数的方法 – 但是最简单的恕我直言是使用开始条件:
%x LEXING_ERROR
%%
// all your rules; the following *must* be at the end
.                 { BEGIN(LEXING_ERROR); yyless(1); }
<LEXING_ERROR>.+  { fprintf(stderr,"Invalid character '%c' found at line %d,"
                            " just before '%s'n",*yytext,yylineno,yytext+1);
                    exit(1);
                  }

注意:确保您已忽略规则中的空格.模式.匹配任何数字,但至少有一个非换行符,或者换句话说,直到当前行的末尾(它将强制flex读取那么远,这应该不是问题). yyless(n)将读指针备份n个字符,所以在之后.规则匹配,它将重新扫描该字符产生(希望)一个半合理的错误消息. (如果您的输入是多字节的,或者具有奇怪的控制字符,那将是不合理的,因此您可以编写更仔细的代码.由您决定.如果错误位于一行的末尾也可能不合理,所以你可能还想写一个更仔细的正则表达式来获取更多的上下文,甚至可能限制读取前向字符的数量.这里有很多选项.)

有关%x和BEGIN的更多信息,请在弹性手册中查找start conditions

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读