在使用* char作为我的YYSTYPE时,我似乎做了一些非常错误的事情,我很新,无法弄清楚自己发生了什么。 Bison要么给我一个语法错误或一个段错误。 Lexer代码和Bison代码可以在下面找到。无论如何,我都非常感谢能帮到我的人......
Lexer代码:
/* token codes */
%{
#include <string.h>
#include "printOut.tab.h"
int decl;
%}
%%
"variables" {decl = 1; return VARS;}
"while" {return WHILE;}
"(" {return OB;}
")" {return CB;}
"{" {decl = 0; return OA;}
"}" {return CA;}
";" {return CP;}
"if" {return IF;}
":=" {return ASGN;}
"=" {return IS;}
"<" {return SML;}
">" {return BIG;}
"/=" {return NIS;}
"+" {return PLS;}
"-" {return MIN;}
"^" {return POW;}
"/" {return DIV;}
"*" {return MUL;}
"||" {return MA;}
"->" {return ARR;}
\\in {return VIS;}
"int"|"string" {yylval.c = strdup(yytext); return TYP;}
[ \t\n] {/*ignore whitespace and newline*/}
[A-Za-z0-9]*(\[[a-zA-Z \.0-9\-\+]+(->)*[a-zA-Z \.0-9\-\+]+\])* {yylval.c = strdup(yytext); return VAR;}
%%
/*main(int argc, char **argv)
{
int tok;
yyin = fopen(argv[1], "r");
while(tok = yylex()) {
if(decl && tok == IS) { tok = VIS; printf("%d ", tok); }
else {
if(tok == VAR){ printf("%s ", yylval); } else { printf("%d ", tok); }
}
}
}*/
野牛代码:
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
%}
%union {
char *c;
}
%token <c> VAR TYP
%token <c> VARS WHILE IF
%token <c> VIS IS NIS MIN PLS POW DIV MUL ASGN MA SML BIG ELSE ARR
%token <c> OB CB OA CA CP
%type <c> vardec constr assign cond expr subexp input dec
%type <c> start
%%
input: /* nothing */
| input constr {printf("%s\n", $1); }
| input start {printf("%s\n", $1); }
| input vardec {printf("%s\n", $1); }
;
start: MIN MIN VAR OA {sprintf($$,"<algorithm=%s/>", $3); }
;
vardec: VARS dec {sprintf($$,"<declarations>%s</declarations>", $2); }
;
dec: TYP VAR VIS VAR CP {sprintf($$,"<declaration type=%s name=%s>%s</declaration>",$1,$2,$4);}
| dec CP TYP VAR VIS VAR CP {sprintf($$,"%s<declaration type=%s name=%s>%s</declaration>",$1,$3,$4,$6);}
;
constr: WHILE OB cond CB OA constr CA CP {sprintf($$,"<construct type=%s><condition>%s</condition><body>%s</body></construct>","while",$3,$6);}
| IF OB cond CB OA constr CA CP {sprintf($$,"<construct type=%s><condition>%s</condition><body>%s</body></construct>","if",$3,$6);}
| IF OB cond CB OA constr CA ELSE OA constr CA CP {sprintf($$,"<construct type=%s><condition>%s</condition><body>%s</body><altbody>%s</altbody></construct>","if",$3,$6,$10);}
| assign CP
| OA constr CA {$$ = $2;}
;
assign: VAR ASGN expr {sprintf($$,"<assignment name=%s>%s</assignment>",$1,$3);}
| assign MA VAR ASGN expr {sprintf($$,"<combinedassignment>%s<assignment name=%s>%s</assignment></combinedassignment>",$1,$3,$5);}
;
cond: VAR {sprintf($$,"<variable name=%s/>",$1);}
| expr IS expr {sprintf($$,"<equality><left>%s</left><right>%s</right></equality>",$1,$3);}
| expr SML expr {sprintf($$,"<smaller><left>%s</left><right>%s</right></smaller>",$1,$3);}
| expr BIG expr {sprintf($$,"<bigger><left>%s</left><right>%s</right></bigger>",$1,$3);}
| expr NIS expr {sprintf($$,"<inequality><left>%s</left><right>%s</right></inequality>",$1,$3);}
;
expr: subexp
| expr PLS subexp {sprintf($$,"<add><left>%s</left><right>%s</right></add>",$1,$3);}
| expr MIN subexp {sprintf($$,"<subtract><left>%s</left><right>%s</right></subtract>",$1,$3);}
/* | MIN expr {sprintf($$,"<subtract><left>%s</left></subtract>",$2);}
*/ | expr POW subexp {sprintf($$,"<power><left>%s</left><right>%s</right></power>",$1,$3);}
/* | OB expr CB {$$ = $2;}
*/;
subexp: VAR {sprintf($$,"<variable name=%s/>",$1);}
| subexp DIV VAR {sprintf($$,"<divide><left>%s</left><right>%s</right></divide>",$1,$3);}
| subexp MUL VAR {sprintf($$,"<multiply><left>%s</left><right>%s</right></multiply>",$1,$3);}
/* | OB subexp CB {$$ = $2;}
*/;
%%
main()
{
while(!feof(stdin)){
yyparse();
}
}
yyerror(char *s)
{
fprintf(stderr, "error: %s\n", s);
}
答案 0 :(得分:2)
您将<c>
声明为规则start
的类型。
<c>
是char *
。这些错误中有更多错误,因此我将使用SEGFAULT
规则解释导致您start
的错误:
$$
是规则的值,所以你实际上是这样做的:
char *result;
sprintf(result,"<algorithm=%s/>", argument);
此示例中的 result
未分配,因此sprintf()
正在尝试写入未分配的内存区域。你需要实现一个像strdup()
这样的函数(你已经在你的词法分析器中使用)接受可变参数,分配正确的内存量然后执行sprintf
- magic:< / p>
char* alloc_string(char *szFormat, ...) {
va_list args;
va_start(args, szFormat);
char szBuffer[1] = "\0";
// vsnprintf() returns the bytes needed (*excluding* the null terminator)
// for a given formatter string and argument list
int nSize = vsnprintf(szBuffer, 0, szFormat, args);
char *szResult = (char *) malloc(1 + nSize);
vsnprintf(szResult, nSize + 1, szFormat, args);
return szResult;
}
毋庸置疑,您负责free()
此功能中的malloc()
内存。