C with Bison+Flex 检查规则文件
C with Bison+Flex Checking File for Rules
这是我的 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
发出错误或消息。我们需要做什么?
您没有遵循 manual 中所示的 lex 程序规范。
虽然您已经指定了一些正则表达式并给它们命名(在定义部分),但您没有告诉 lex 在找到某些正则表达式时要做什么(在规则部分,您将其留空)。添加一个 returns 令牌的规则部分,如下所示:
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;
%%
您的 bison 代码没有 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 工具有时会生成导致这些警告的代码。这些只是 warnings 而不是 errors 并且可以忽略。如果您不想看到它们,您可以将选项 -ansi
放在 gcc
编译行上。
您的代码现在可以 运行 - 我已经测试过了。
如果您收到类似 main not defined 的错误,则说明您没有提供 yacc 库(-ly 在 gcc 行),但您可以输入自己的 main程序:
%{
#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"
现在您将看到它编译并 运行s,但是每个 html 文件都会给您一个语法错误。这是因为您的野牛语法不正确。您只允许一个 space 或一个 html 文件中的一个字符(而不是它们的序列)。如果你不能解决那个问题,你需要问另一个问题——或者更仔细地阅读你的老师 class 笔记!
这是我的 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
发出错误或消息。我们需要做什么?
您没有遵循 manual 中所示的 lex 程序规范。
虽然您已经指定了一些正则表达式并给它们命名(在定义部分),但您没有告诉 lex 在找到某些正则表达式时要做什么(在规则部分,您将其留空)。添加一个 returns 令牌的规则部分,如下所示:
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;
%%
您的 bison 代码没有 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 工具有时会生成导致这些警告的代码。这些只是 warnings 而不是 errors 并且可以忽略。如果您不想看到它们,您可以将选项 -ansi
放在 gcc
编译行上。
您的代码现在可以 运行 - 我已经测试过了。
如果您收到类似 main not defined 的错误,则说明您没有提供 yacc 库(-ly 在 gcc 行),但您可以输入自己的 main程序:
%{
#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"
现在您将看到它编译并 运行s,但是每个 html 文件都会给您一个语法错误。这是因为您的野牛语法不正确。您只允许一个 space 或一个 html 文件中的一个字符(而不是它们的序列)。如果你不能解决那个问题,你需要问另一个问题——或者更仔细地阅读你的老师 class 笔记!