首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Lex -识别令牌

Lex -识别令牌
EN

Stack Overflow用户
提问于 2012-01-16 13:05:55
回答 1查看 7.6K关注 0票数 2

我在努力学习莱克斯。我有一个简单的程序,我想要在文件中读取并识别令牌。

现在我得到了一些错误。我想我遇到了问题,因为文件中有多行可以识别令牌?

这是文件

代码语言:javascript
复制
fd 3x00
bk
setc 100
int xy3 fd 10 rt 90

以下是我试图实现的输出:

代码语言:javascript
复制
Keyword: fd
Illegal: 3x00
Keyword: bk
Keyword: setc
Number: 100
Keyword: int

下面是我的程序:

代码语言:javascript
复制
%{

/* Comment  */

 #include <stdio.h>
 #include <stdlib.h>

%}
%%
fd                     {printf("Keyword: fd\n");}
[0-9][a-z][0-9]        {printf("Illegal: 3x00\n");}
bk                     {printf("Keyword: bk\n");}
setc[0-9]              {printf("Keyword: setc\n Number: %s\n", yytext);}
int                    {printf("Keyword: int\n");}
xy3                    {printf("ID: xy3\n");}
fd[0-9]                {printf("Keyword: fd\n Number %s\n", yytext);}
rt[0-9]                {printf("Keyword: rt \n Number %s\n", yytext);}
%%

main( argc, argv)
int argc;
char** argv;
{
    if(argc > 1)
    {

        FILE *file;
        file = fopen(argv[1], "r");
        if(!file)
        {
           fprintf(stderr, "Could not open %s \n", argv[1]);
           exit(1);
        }

        yyin = file;

    }

    yylex();

}

以下是我在尝试编译它时得到的错误:

代码语言:javascript
复制
 In function 'yylex':
miniStarLogo.l:11: error: expected expression before '[' token
miniStarLogo.l:11: error: 'a' undeclared (first use in this function)
miniStarLogo.l:11: error: (Each undeclared identifier is reported only once
miniStarLogo.l:11: error: for each function it appears in.)
miniStarLogo.l:11: error: expected ';' before '{' token
miniStarLogo.l:13: error: expected expression before '[' token
miniStarLogo.l:13: error: expected ';' before '{' token

是我的printf语句中的错误吗?谢谢

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-01-16 13:39:10

当我在MacOS X (10.7.2)上用flex (2.5.35)和gcc (4.6.1)编译你的代码时,我从C编译器得到的唯一抱怨是关于main()的非原型定义,那是因为我总是在编译时启用该警告并提到yyunput() defined but not used (这不是你的错)。

由于您正在学习C语言,因此您应该只使用符号:

代码语言:javascript
复制
int main(int argc, char **argv)
{
    ...
}

或者是等效的。

我还将miniStarLogo.l文件转换为DOS格式(CRLF行结尾),flexgcc似乎都可以接受结果-有点让我惊讶。在您的机器上可能不是这样。

当我在你的测试数据上运行代码时,我得到:

代码语言:javascript
复制
Keyword: fd
 Illegal: 3x00
0
Keyword: bk

setc 100
Keyword: int
 ID: xy3
 Keyword: fd
 10 rt 90

所以,根据我的估计,你离你需要的地方不远了。

我的命令令人困惑。

我用的是(嗯,是GCC 4.2.1而不是4.6.1),但是:

代码语言:javascript
复制
$ flex miniStarLogo.l
$ gcc -Wall -Wextra -O3 -g -o lex.yy lex.yy.c -lfl
miniStarLogo.l:22: warning: return type defaults to ‘int’
miniStarLogo.l: In function ‘main’:
miniStarLogo.l:42: warning: control reaches end of non-void function
miniStarLogo.l: At top level:
lex.yy.c:1114: warning: ‘yyunput’ defined but not used
$ ./lex.yy <<EOF
> fd 3x00
> bk
> setc 100
> int xy3 fd 10 rt 90
> EOF
Keyword: fd
 Illegal: 3x00
0
Keyword: bk

setc 100
Keyword: int
 ID: xy3
 Keyword: fd
 10 rt 90
$

(好吧-我稍微作弊了:第一次,我运行了rmk lex.yy LDLIBS=-lfl,其中rmkmake的变体,目录中的编译规则使用所示的命令行。但我重做了编译,以获得正确的错误消息,与上面完全相同。)

你可能需要考虑扩展你的模式,用[0-9]+代替[0-9]来接受“一个或多个”数字。您可能需要查看处理不匹配字符的规则。就我个人而言,我竭尽全力避免在换行符之前出现空格,因此您需要收紧打印格式以满足我的标准。然而,这与让程序运行没有关系。

此外,如果您需要将文件从DOS转换为Unix行结尾,最简单的方法是dos2unix命令,如果您的机器上有该命令的话。否则,请使用:

代码语言:javascript
复制
$ tr -d '\015' < miniStarLogo.l > x
$ od -c x
0000000   %   {  \r  \n  \r  \n   /   *       C   o   m   m   e   n   t
...
0001560  \n   }  \r  \n
0001564
$ mv x miniStarLogo.l
$

我使用vim:set fileformat=dos小心地添加了回车;也可以使用vim:set fileformat=unix撤销它。这是Unix,所以TMTOWTDI (有不止一种方法可以做到这一点-- Perl座右铭),我甚至不打算使用Perl。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8875974

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档