mas*_*ief 5 yacc compiler-theory
我应该写一个程序来做 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;
}
Run Code Online (Sandbox Code Playgroud)
我的问题是每个表达式只能有 1 种类型。现在一切基本上都是浮动的,所以虽然操作是正确的,但这不是正确的解决方案。
我想定义更多的表达式,基本上有 factor_int 和 factor_float,然后替换其中的所有内容,但这似乎是错误的。我不知道如何完成这项工作,而且我看到的教程并没有真正帮助我。
基本上你可以做这样的事情:
%{
#include <stdio.h>
#include <ctype.h>
struct number
{
union
{
int ival;
float fval;
}
char type;
}
char INT_TYPE = 1;
char FLOAT_TYPE = 2;
%}
%union
{
struct number value;
}
%token <value> FLOAT INTEGER command exp term factor
int yylex()
{
...
if(f1 == 0)
{
yylval.value.type = INT_TYPE;
yylval.value.ival = 0
}
...
}
Run Code Online (Sandbox Code Playgroud)
等等..
通过这种方式,您可以在减少规则时检查操作数,确保生成新的正确类型..例如:
exp : exp '+' term {
if ($1.type == INT_TYPE && $3.type == INT_TYPE)
{
$$.type = INT_TYPE;
$$.ival = $1.ival + $3.ival;
}
else if ($1.type == INT_TYPE && $3.type == FLOAT_TYPE)
{
// this is a sort of implicit conversion to float
$$.type = FLOAT_TYPE;
$$.fval = $1.ival + $3.fval;
}
// and so on
}
Run Code Online (Sandbox Code Playgroud)
附言。我用 Flex+Bison 做了类似的事情,我不知道 Lex+Yacc 是否支持所有内容,但我认为是的。
| 归档时间: |
|
| 查看次数: |
5506 次 |
| 最近记录: |