开发者

Bison throws me a segfault, assuming it has something to do with *char

I seem to be doing something very wrong in the use of *char as my YYSTYPE, I'm pretty new and unable to figure out myself what is going on. Bison either giv开发者_JAVA百科es me a syntax error or a segfault. Lexer code and Bison code can be found below. I'd be very thankful to anyway who can help me out here...

Lexer code:

/* 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); }
    }
   }
}*/

Bison code:

%{
#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);
}


You declared <c> as a type for rule start.

<c> in turn, is char *. There are more of these errors, so I'll explain the one leading to your SEGFAULT with the start rule:

$$ is the rule's value, so you're practically doing this:

char *result;
sprintf(result,"<algorithm=%s/>", argument);

result in this example is not allocated, so sprintf() is attempting to write to an unallocated memory region. You'll need to implement a function like strdup() (which you're using in your lexer, already) that accepts variadic arguments, allocates the proper ammount of memory and then does the sprintf-magic:

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;
}

Needless to say, you're responsible for free()ing the memory malloc()ed in this function.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜