这是我的html.l:
DOC_START "<html>"|"<HTML>"
DOC_END "</html>"|"</HTML>"
SPACE " "
TEXT .
%%
%%
这是我的html.y:
%{
#include "lex.yy.c"
%}
%%
Doc : DOC_START Other DOC_END
Other : TEXT
| SPACE
%%
这是我的html文件:
<HTML>
foo bar
</HTML>
我正在编译第一个flex文件,在bison文件之后。它会出现has no rules
错误。
我想检查一下这个文件是否是Doc
语句中描述的正确的html文件。并且预计会向stdout
发送错误或消息。我们需要做什么?
答案 0 :(得分:5)
您没有遵循manual所示的lex程序规范。
虽然你已经指定了一些正则表达式并给出了它们的名字(在定义部分中),但你没有告诉lex在找到它时要做什么(在规则部分,你留空)。添加一个返回令牌的规则部分,如下所示:
DOC_START "<html>"|"<HTML>"
DOC_END "</html>"|"</HTML>"
SPACE " "
TEXT .
%%
{DOC_START} return DOC_START;
{DOC_END} return DOC_END;
{SPACE} return SPACE;
{TEXT} return TEXT;
%%
您的野牛代码没有specified the tokens that are coming from lex,因此您需要添加:
%{
#include "lex.yy.c"
%}
%token DOC_START DOC_END TEXT SPACE
%%
Doc : DOC_START Other DOC_END
Other : TEXT
| SPACE
%%
但是,如果你这样做,则在令牌声明之前编译lex代码。要解决此问题,请将include放在文件的底部:
%token DOC_START DOC_END TEXT SPACE
%%
Doc : DOC_START Other DOC_END
Other : TEXT
| SPACE
%%
#include "lex.yy.c"
差不多......
现在要输出错误消息,我们需要为yyerror
函数提供代码。您希望输出转到stdout
;我们需要标准的IO库stdio.h
:
%{
#include <stdio.h>
void yyerror(const char* s);
%}
%token DOC_START DOC_END TEXT SPACE
%%
Doc : DOC_START Other DOC_END
Other : TEXT
| SPACE
%%
void yyerror(const char* s)
{
fprintf(stdout, "Syntax error: %s\n", s);
}
#include "lex.yy.c"
现在我注意到您的编译器遵循C99标准并在implicit-function-declarations
上发出警告。工具flex和bison有时会生成导致这些警告的代码。这些只是警告而非错误,可以忽略。如果您不想看到它们,可以在-ansi
编译行上添加gcc
选项。
您的代码现在将运行 - 我测试了它。
如果您收到的错误如 main 未定义,则您尚未提供yacc库(-ly在gcc行上),但您只需键入自己的主程序:
%{
#include <stdio.h>
void yyerror(const char* s);
%}
%token DOC_START DOC_END TEXT SPACE
%%
Doc : DOC_START Other DOC_END
Other : TEXT
| SPACE
%%
void yyerror(const char* s)
{
fprintf(stdout, "Syntax error: %s\n", s);
}
int main (void)
{
return(yyparse());
}
#include "lex.yy.c"
现在您将看到它编译并运行,但每个html文件都会给您一个语法错误。这是因为你的野牛语法不正确。您只允许在html文件中使用一个单独的空格或一个单个字符(而不是它们的序列)。如果你无法解决这个问题,你需要提出另一个问题 - 或者更仔细地阅读你的老师课堂笔记!