Yacc - 语句 - 语法规则
我有一个小程序,可以读取输入并将数据返回到 yacc 文件,我只想打印出来。 我认为我没有正确理解 yacc 文件中的语法规则。
我得到 NULL 值,但有些内容没有打印,并且
输入文件存在语法错误:
fd
bk 100
setc
int
fd 10 rt 90
这是 yacc 文件:
%{
#include <ctype.h>
#include <stdio.h>
%}
%token NUMBER
%token ID
%token FD
%token BK
%token SETC
%token RT
%token INT
%%
statement : command arg {printf("KEYWORDS: %s\n", $1);}
|command {printf("OR-> %s\n", $1);}
;
command : FD {$$ = $1; printf("FD-> %s\n", $1);}
|BK {$$ = $1; printf("BK-> %s\n", $1);}
|SETC {$$ = $1; printf("SETC-> %s\n", $1); }
|INT {$$ = $1; printf("INT-> %s\n", $1);}
|RT {$$ = $1; printf("RT-> %s\n", $1);}
;
arg : NUMBER {$$ = $1; printf("NUMBER-> %d\n", $1);}
;
%%
这是 lex 文件:
%{
#include "y.tab.h"
#include "stdio.h"
#include <stdlib.h>
%}
%%
fd {return FD; }
bk {return BK;}
setc {return SETC;}
[-+]?[0-9]+ { yylval = atoi(yytext); return NUMBER;}
int {return INT;}
rt {return RT;}
. {printf("%s\n", yytext);}
%%
这是输出:
BK-> (null)
NUMBER-> 100
KEYWORDS: (null)
syntax error
那么为什么它只打印 BK 而不是其余的?为什么我得到 NULL 值?为什么我有语法错误?
抱歉,有 3 个问题
i have a small program that reads input and returns data to a yacc file where i just want to print out.
I am not understanding the grammar rules correctly in the yacc file i think.
I am getting NULL values and somethings are not printing and a syntax error
here is the input file:
fd
bk 100
setc
int
fd 10 rt 90
Here is the yacc file:
%{
#include <ctype.h>
#include <stdio.h>
%}
%token NUMBER
%token ID
%token FD
%token BK
%token SETC
%token RT
%token INT
%%
statement : command arg {printf("KEYWORDS: %s\n", $1);}
|command {printf("OR-> %s\n", $1);}
;
command : FD {$ = $1; printf("FD-> %s\n", $1);}
|BK {$ = $1; printf("BK-> %s\n", $1);}
|SETC {$ = $1; printf("SETC-> %s\n", $1); }
|INT {$ = $1; printf("INT-> %s\n", $1);}
|RT {$ = $1; printf("RT-> %s\n", $1);}
;
arg : NUMBER {$ = $1; printf("NUMBER-> %d\n", $1);}
;
%%
Here is the lex file:
%{
#include "y.tab.h"
#include "stdio.h"
#include <stdlib.h>
%}
%%
fd {return FD; }
bk {return BK;}
setc {return SETC;}
[-+]?[0-9]+ { yylval = atoi(yytext); return NUMBER;}
int {return INT;}
rt {return RT;}
. {printf("%s\n", yytext);}
%%
Here is the output:
BK-> (null)
NUMBER-> 100
KEYWORDS: (null)
syntax error
So why is it only printing BK and not the rest? Why am i getting NULL values? And why do i have a syntax error?
Sorry there's 3 questions
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
首先,您的语法只接受单个语句,因此它会解析第一个语句,然后给出语法错误,因为下一个读取的内容不是 EOF。尝试在
statement
的规则之前添加以下内容:这将使解析器在 EOF 之前解析任意数量的语句(0 或更多)
其次,您的词法分析器不会为关键字设置 yylval,而您的解析器期望它这样做(它在对应于关键字标记的操作中访问
$1
),因此它会得到随机垃圾。在这种情况下,它恰好是传递给 printf 的 NULL ——你很幸运它没有崩溃。要解决此问题,您需要在 yylval 中返回一些内容(也许是 yytext 中的字符串),但由于您没有将其定义为其他内容,因此 yylval 只是一个 int,因此不能保存字符串。您可以使用
%union
使 yylval 成为一个可以容纳int
或char *
的联合,但这仍然会给您留下一个巨大的空间。内存管理问题为字符串分配空间并释放它(如果您不希望内存泄漏)。最简单的方法是在这些操作中删除对$1
的引用,因为您实际上并不需要它。First, your grammar only accepts a single statement, so it parses the first statement and then gives a syntax error as the next thing read is not an EOF. Try adding the following before the rule for
statement
:This will let the parser parse any number of statements (0 or more) before an EOF
Second, your lexer doesn't set yylval for keywords, while your parser expects it to (it accesses
$1
in actions where that corresponds to a keyword token), so it gets random garbage. In this case it happens to be a NULL that it passes to printf -- you're lucky it didn't crash.To fix this, you'll need to return something in yylval (the string in yytext, perhaps), but as you haven't defined it as anything else, yylval is just an int, so can't hold a string. You can use
%union
to make yylval a union that can hold either anint
or achar *
, but that still leaves you with a huge memory management problem allocating space for strings and freeing it if you don't want memory leaks. Easiest would be to get rid of the references to$1
in those actions, as you don't really need it.