【发布时间】:2010-03-02 20:42:21
【问题描述】:
我应该编写一个执行 2 + 2 = 4 和 2.2 + 2 = 4.2 的程序。
我已经这样做了,因此它将所有内容都视为浮点数,但这是“错误的”。我必须区分它们。到目前为止,这是我所拥有的:
%{
#include <stdio.h>
#include <ctype.h>
%}
%token <dval> FLOAT
%token <ival> INTEGER
%union
{
float dval;
int ival;
}
%type <dval> command exp term factor
%%
command : exp {printf("%f\n",$1);}
;
exp : exp '+' term {$$ = $1 + $3;}
| exp '-' term {$$ = $1 - $3;}
| term {$$ = $1;}
;
term : term '*' factor {$$ = $1 * $3;}
| factor {$$ = $1;}
;
factor : '(' exp ')' {$$ = $2;}
| FLOAT {$$ = $1;}
| INTEGER {$$ = $1;}
;
%%
int main()
{
return yyparse();
}
int yylex()
{
int c;
while( (c=getchar()) == ' ');
if( isdigit(c) )
{
ungetc(c, stdin);
float f1;
scanf("%f", &f1);
int i1 = (int) f1;
if(f1 == 0)
{
yylval.ival = 0;
return INTEGER;
}
else if( (((float) i1) / f1 ) == 1)
{
yylval.ival = i1;
return INTEGER;
}
else
{
yylval.dval = f1;
return FLOAT;
}
//scanf("%f",&yylval.dval);
//return(NUMBER);
}
if(c == '\n') return 0;
return c;
}
int yyerror(char *s)
{
fprintf(stderr,"%s\n",s);
return 0;
}
我遇到的问题是每个表达式只能有一种类型。现在一切基本上都是浮动的,所以虽然操作是正确的,但这不是正确的解决方案。
我想过定义更多的表达式,基本上有factor_int和factor_float,然后替换其中的所有内容,但这似乎真的错了。我不知道如何完成这项工作,而且我看到的教程并没有真正帮助我。
【问题讨论】:
-
我认为 factor_int 和 factor_float 方法是正确的。这基本上就是真正的编译器的工作方式。每个表达式要么是浮点数,要么是整数。
-
所以如果我有 8 种不同的类型,我会拥有 2^8 个表达式和 2 个操作数?太疯狂了!!!或者我做错了数学。
-
你听说过 lex 吗?我认为较新的称为 flex。
-
是的,我用过一点,但我不明白如何将 yacc 与它很好地集成。我看到的教程没有递归,比如
$$ = $1 + $3。 -
您可以使用 lex 来生成您的 yylex 方法。您不必自己实现它。正常流程是,有一个 lex 文件,它会生成一个 .c 文件,您可以将其与 yacc 文件一起编译以获得解析器。
标签: yacc compiler-theory