compiler-construction - Yacc 打印一个与指定变量不同的联合变量
问题描述
我正在尝试在 flex/yacc 中实现一个计算器,它也将支持实数(我还没有实现它们)。但由于某种原因,我的代码没有打印表达式的值,而是只打印表达式的类型,整数为 1。这是弹性文件
%{
#include <stdio.h>
#include "y.tab.h"
int c;
%}
%%
" " ;
[a-z] {
c = yytext[0];
yylval.a = c - 'a';
return(LETTER);
}
[0-9] {
c = yytext[0];
yylval.a = c - '0';
return(DIGIT);
}
[^a-z0-9\b] {
c = yytext[0];
return(c);
}
%%
这是yacc文件
%{
#include <stdio.h>
#include <math.h>
int iregs[26];
double dregs[26];
char type[26];
int base = 10;
void yyerror(char*);
int yywrap();
int yyparse();
int yylex();
%}
%start list
%union
{
int a;
double b;
char type; /* 0 for double , 1 for integer */
}
%token DIGIT LETTER
%left '|'
%left '&'
%left '+' '-'
%left '*' '/' '%'
%left UMINUS /*supplies precedence for unary minus */
%% /* beginning of rules section */
list: /*empty */
|
list stat '\n'
|
list error '\n'
{
yyerrok;
}
;
stat: expr
{
if($1.type) {
printf("%d\n",$1.a);
}
else {
printf("%f\n",$1.b);
}
}
|
LETTER '=' expr
{
if($3.type) {
iregs[$1.a] = $3.a;
type[$1.a] = 1;
}
else {
dregs[$1.a] = $3.b;
type[$1.a] = 0;
}
}
;
expr: '(' expr ')'
{
$$ = $2;
}
|
expr '*' expr
{
if($1.type && $3.type) { /* both integers */
$$.a = $1.a * $3.a;
$$.type = 1;
}
else if (!$1.type && !$1.type) { /* both doubles */
$$.b = $1.b * $3.b;
$$.type = 0;
}
else if ($1.type && !$3.type) { /* first integer second double */
$$.b = $1.a * $3.b;
$$.type = 0;
}
else { /* first double second integer */
$$.b = $1.b * $3.a;
$$.type = 0;
}
}
|
expr '/' expr
{
if($1.type && $3.type) { /* both integers */
$$.a = $1.a / $3.a;
$$.type = 1;
}
else if (!$1.type && !$1.type) { /* both doubles */
$$.b = $1.b / $3.b;
$$.type = 0;
}
else if ($1.type && !$3.type) { /* first integer second double */
$$.b = $1.a / $3.b;
$$.type = 0;
}
else { /* first double second integer */
$$.b = $1.b / $3.a;
$$.type = 0;
}
}
|
expr '%' expr
{
if($1.type && $3.type) { /* both integers */
$$.a = $1.a % $3.a;
$$.type = 1;
}
else { /* at least one double */
yyerror("% is applied to integers only");
}
}
|
expr '+' expr
{
if($1.type && $3.type) { /* both integers */
$$.a = $1.a + $3.a;
$$.type = 1;
}
else if (!$1.type && !$1.type) { /* both doubles */
$$.b = $1.b + $3.b;
$$.type = 0;
}
else if ($1.type && !$3.type) { /* first integer second double */
$$.b = $1.a + $3.b;
$$.type = 0;
}
else { /* first double second integer */
$$.b = $1.b + $3.a;
$$.type = 0;
}
}
|
expr '-' expr
{
if($1.type && $3.type) { /* both integers */
$$.a = $1.a - $3.a;
$$.type = 1;
}
else if (!$1.type && !$1.type) { /* both doubles */
$$.b = $1.b - $3.b;
$$.type = 0;
}
else if ($1.type && !$3.type) { /* first integer second double */
$$.b = $1.a - $3.b;
$$.type = 0;
}
else { /* first double second integer */
$$.b = $1.b - $3.a;
$$.type = 0;
}
}
|
expr '&' expr
{
if($1.type && $3.type) { /* both integers */
$$.a = $1.a & $3.a;
$$.type = 1;
}
else { /* at least one double */
yyerror("& is applied to integers only");
}
}
|
expr '|' expr
{
if($1.type && $3.type) { /* both integers */
$$.a = $1.a | $3.a;
$$.type = 1;
}
else { /* at least one double */
yyerror("| is applied to integers only");
}
}
|
'-' expr %prec UMINUS
{
if($2.type) {
$$.a = -$2.a;
$$.type = 1;
}
else {
$$.b = -$2.b;
$$.type = 0;
}
}
|
LETTER
{
if(type[$1.a]) {
$$.a = iregs[$1.a];
$$.type = 1;
}
else {
$$.b = dregs[$1.a];
$$.type = 0;
}
}
|
integer
{
$$.a = $1.a;
$$.type = 1;
}
;
integer: DIGIT
{
$$.a = $1.a;
}
|
integer DIGIT
{
$$.a = base * $1.a + $2.a;
}
;
%%
int main()
{
return(yyparse());
}
void yyerror(s)
char *s;
{
fprintf(stderr, "%s\n",s);
}
int yywrap()
{
return(1);
}
因为我在我的测试文件中使用整数,所以无论我使用什么表达式,这段代码都只打印 1,我不知道为什么。
解决方案
每个标记和语法规则只能使用联合中的一个值,而不是整个联合作为结构。
推荐阅读
- apache - Apache 服务器将我带到错误的 URL 但仅针对一个链接
- java - 在java中,如何处理最多N个线程的有界队列中的项目,N可调?
- swift - 闭包表达式未使用 swift 3
- sql-server-2008 - 在 SQL Server 中合并两行
- github - 用 Webhooks 替换 Github 电子邮件服务
- xpath - Xpath获取省略子节点的主要段落文本
- python-3.x - 如果任何列中的值介于两个值之间,则选择 DataFrame 中的行
- c++ - 从 QMap 获取 Java 风格的迭代器
不指定 T, K - java - 如何使用java存储或以任何方式连接到mysql数据库
- node.js - https.get() 不返回 UTF-8 字符