我正在尝试构建一个可以进行逐位运算的计算器。我的代码可以正确编译。但是当我运行它并输入任何值时,就会发生分段错误。我想知道你是否可以帮助我。
.l 文件
%}
%option noyywrap
%%
[0-9]+ {
yylval.dval=atof(yytext);
return INTEGER;
}
([0-9]+|([0-9]*\.[0-9]+)([eE][-+]?[0-9]+)?) {
yylval.dval = atof(yytext);
return NUMBER;
}
[ \t ] ;
[A-Za-z][A-Za-z0-9]* {
struct symtab *sp = symlook(yytext);
yylval.dval = 0.0;
return NAME;
}
"**" {
return POW;
}
"<<" {
return LSHIFT;
}
">>" {
return RSHIFT;
}
"$" { return 0; }
\n |
. return yytext[0];
%%
.h 文件
#define NSYMS 20
struct symtab {
char *name;
double (*funcptr)();
double dval;
enum constype {integer, floatingpoint} constype;
} symtab[NSYMS];
struct symtab *symlook();
.y 文件
%{
#include "zcalc.h"
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
int flag = 0;
void yyerror( char *mesg ); /* yacc error checker */
%}
%union {
double dval;
struct symtab *symp;
}
%token <symp> NAME
%token <dval> NUMBER
%token <dval> INTEGER
%token POW
%token LSHIFT
%token RSHIFT
%left '-' '+'
%left '*' '/'
%type <symp> expression
%%
statement_list: statement '\n'
| statement_list statement '\n'
statement: NAME '=' expression {$1->dval = $3->dval;
if($3- >constype==integer)
$1- >constype=integer;
else
$1- >constype=floatingpoint;}
| expression { printf("= %g\n", $1->dval); }
expression: '+' expression expression { $$->dval = $2->dval + $3->dval;
if($2->constype==integer && $3->constype)
$$->constype=integer;
else $$->constype=floatingpoint;
}
| '-' expression expression { $$->dval = $2->dval - $3->dval;
if($2->constype==integer && $3->constype)
$$->constype=integer;
else $$->constype=floatingpoint;}
| '*' expression expression { $$->dval = $2->dval * $3->dval;
if($2->constype==integer && $3->constype)
$$->constype=integer;
else $$->constype=floatingpoint;}
| '/' expression expression { $$->dval = $2->dval / $3->dval;
if($2->constype==integer && $3->constype)
$$->constype=integer;
else $$->constype=floatingpoint;}
| '(' expression ')' { $$->dval = $2->dval;
if($2->constype==integer)
$$->constype=integer;
else $$->constype=floatingpoint;}
| '&' expression expression {
if($2->constype!=integer||$3->constype!=integer)
$$->dval = (int)($2->dval) & (int)($3->dval);
else
printf("Error: bitewise operations cannot be done to floating point vals./n")}
| '|' expression expression {
if($2->constype!=integer||$3->constype!=integer)
$$->dval = (int)($2->dval) | (int)($3->dval);
else
printf("Error: bitewise operations cannot be done to floating point values./n")}
| '^' expression expression {
if($2->constype!=integer||$3->constype!=integer)
$$->dval = (int)($2->dval) ^ (int)($3->dval);
else
printf("Error: bitewise operations cannot be done to floating point values./n")}
| '~' expression {
if($2->constype!=integer)
$$->dval = ~(int)($2->dval);
else
printf("Error: bitewise operations cannot be done to floating point values./n")}
| LSHIFT expression expression {
if($2->constype!=integer||$3->constype!=integer)
$$->dval = (int)$2->dval << (int)$3->dval;
else
printf("Error: bitewise operations cannot be done to floating point values./n")}
| RSHIFT expression expression {
if($2->constype!=integer||$3->constype!=integer)
$$->dval = (int)$2->dval >> (int)$3->dval;
else
printf("Error: bitewise operations cannot be done to floating point values./n")}
| POW expression expression { $$->dval=pow($2->dval,$3->dval);}
| NUMBER {$$->dval=$<dval>1;
$$->constype=floatingpoint;
}
| INTEGER {
$$->dval=$<dval>1;
$$->constype=integer;}
| NAME {
$$->dval = $1->dval;
if($1->constype==integer )
$$->constype=integer;
else $$->constype=floatingpoint;}
%%
struct symtab * symlook( char *s ) {
char *p;
struct symtab *sp;
for(sp = symtab; sp < &symtab[NSYMS]; sp++) {
/* is it already here? */
if (sp->name && !strcmp(sp->name, s))
return sp;
/* is it free */
if (!sp->name) {
sp->name = strdup(s);
return sp;
}
/* otherwise continue to the next */
}
yyerror("Too many symbols...\n");
exit(1);
}
void addfunc( char *name, double (*func)() ) {
struct symtab *sp = symlook(name);
sp->funcptr = func;
}
/* yacc error function */
void yyerror( char *mesg ) {
flag = 1;
printf("%s \n" , mesg);
}
int main() {
yyparse();
return 0;
}
任何帮助将不胜感激!