c - 在 bison 中使用 $2 时出现段错误

标签 c compiler-construction grammar bison flex-lexer

我正在尝试为编译器生成中间代码。我实现了一个堆栈来推送其中的一些关键字,但是当我使用 pushS($2) 时,出现段错误。我能做些什么来纠正这个问题? 这是我的 lex 文件:

%{
#include "all.h"    
#include<stdbool.h>
#include <stdlib.h>
#include <string.h>
//#include "LinkedList.h"
#include "parser.tab.h"
char* tempString;
%}
%option yylineno

whole   0|[1-9][0-9]*
real    {whole}\.(([0-9])|([0-9][0-9]*[1-9]))
divisionop [/]
noSymbol    [^ \t\n\/\+\-\*\:\;\,\(\)\.]
error   {noSymbol}+

%%


[ \t\n\r]+  ;



\#[-+]?{whole}/[\ :\,\;\+\-\/\*\)\n\r]|".GT."|".GE."|".EQ."|".NE."|".LT."|".LE."|":="   {

    char* string = (char*) malloc(strlen(yytext));
    strcpy(string, yytext + 1);
    string[strlen(string)] = 0;
    printf("Found integer : %d\n", atoi(string));
    //push(string,INTEGER,yylineno);
    return INTEGER;}


\#[-+]?{real}/[\ :\,\;\+\-\/\*\)\n\r]|".GT."|".GE."|".EQ."|".NE."|".LT."|".LE."|":="    {
    char* string = (char*) malloc(strlen(yytext));
    strcpy(string, yytext + 1);
    string[strlen(string)] = 0;
    printf("Found real:%s\n",string);
    //push(string,REAL,0);
    return REALNUM;
}

[a-zA-Z][0-9][0-9a-zA-Z]*   {
    printf("Found identifier:%s\n",yytext);
    //yylval.str = yytext;
    //printf("****lvalue is:%s\n",yylval.str);
    //push(yytext,IDENTIFIER,yylineno);
    tempString = (char*) malloc(strlen(yytext));
    strcpy(tempString, yytext);
    return IDENTIFIER;
}

Program {
    printf("Found program :%s\n",yytext);
    return PROGRAM;

}

Int {
    printf("Found int :%s\n",yytext);
    return INT;

}

Real    {
    printf("Found real :%s\n",yytext);
    return REAL;

}

Bool    {
    printf("Found bool :%s\n",yytext);
    return BOOL;

}

Procedure   {
    printf("Found real :%s\n",yytext);
    return PROCEDURE;

}

Function    {
    printf("Found function :%s\n",yytext);
    return FUNCTION;

}

Begin   {
    printf("Found begin :%s\n",yytext);
    return BEGINN;

}

End {
    printf("Found end :%s\n",yytext);
    return END;

}

If  {
    printf("Found if :%s\n",yytext);
    return IF;
}

Then {
    printf("Found then :%s\n",yytext);
    return THEN;

}

Else {
    printf("Found else :%s\n",yytext);
    return ELSE;
}

While {
    printf("Found while :%s\n",yytext);
    return WHILE;
}

Do {
    printf("Found do :%s\n",yytext);
    return DO;
}

For {
    printf("Found for :%s\n",yytext);
    return FOR;
}

To {
    printf("Found to :%s\n",yytext);
    return TO;
}

Downto {
    printf("Found downto :%s\n",yytext);
    return DOWNTO;
}

Case {
    printf("Found case :%s\n",yytext);
    return CASE;
}

Return {
    printf("Found return :%s\n",yytext);
    return RETURN;
}

"And Then" {
    printf("Found andthen :%s\n",yytext);
    //push(yytext,ANDTHEN,yylineno);
    return ANDTHEN;
}

"Or Else" {
    printf("Found andthen :%s\n",yytext);
    //push(yytext,ORELSE,yylineno);
    return ORELSE;
}

"+" {
    printf("Found plus :%s\n",yytext);
    return PLUS;
}

\-  {
    printf("Found minus :%s\n",yytext);
    return MINUS;

}

\*  {
    printf("Found multiply :%s\n",yytext);
    return MULTIPLY;
}

{divisionop}    {
    printf("Found division :%s\n",yytext);
    //push(yytext,DIVISION,yylineno);
    return DIVISION;
}

".GT."  {
    printf("Found greaterthan :%s\n",yytext);
    return GREATERTHAN;
}

".GE."  {
    printf("Found greaterequal :%s\n",yytext);
    return GREATEREQUAL;
}

\.NE\.  {
    printf("Found notequal :%s\n",yytext);
    return NOTEQUAL;
}

\.EQ\.  {
    printf("Found EQUAL :%s\n",yytext);
    return EQUAL;
}

\.LT\.  {
    printf("Found lessthan :%s\n",yytext);
    return LESSTHAN;
}

\.LE\.  {
    printf("Found lessequal :%s\n",yytext);
    return LESSEQUAL;
}

[,] {
    printf("Found comma :%s\n",yytext);
    return COMMA;
}

":="    {
    //printf("Found declare :%s\n",yytext);
    return DECLARE;
}

[:] {
    printf("Found semicolon :%s\n",yytext);
    return COLON;
}

[;] {
    printf("Found semicolon :%s\n",yytext);
    return SEMICOLON;
}


\( {
    printf("Found oppar :%s\n",yytext);

    return OPPAR;

}

\)  {
    printf("Found cppar :%s\n",yytext);
    return CPAR;
}

False   {
    printf("Found false :%s\n",yytext);
    return FALSE;
}

True    {
    printf("Found true :%s\n",yytext);
    return TRUE;
}

{error} {
    printf("Error on : **<<  %s  >>**\n", yytext);
    //yymore();
}
\.  {
    printf("Error on : **<<  illegal use of \" %s \" >>**\n", yytext);
    //yymore();
}

%%


int yywrap(){
    return 1;
}

//int main(){
//  yyin = fopen("input2P.txt", "r");
//  initLinkedList(table);
//  while(yylex());
//  printLinkedList();
//  return 0;
//}

这是我的解析器

%{
#include "all.h"
#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include <stdlib.h>
#include "stack.h"
#include "stack_arith.h"
//#include "LinkedList.h"
//#include "symbol_table.h"

int currentType;
char* returnType;

extern FILE* yyin;
extern char* tempString;
struct Stack* tblptrStack;

Eval* codegen();

/*
int t = 0;
  char* new_temp(char *c){
    char num[5];
    char tmp[10] = "t";
      snprintf(num,5,"%d",t);
      strcat(tmp,num);
      printf("%s",tmp);
      t++;
      return tmp;
    }
*/

int yylex();
void yyerror(char* error);
struct SymbolTable* secondArg(struct SymbolTable* a,struct SymbolTable* b );
%}

%union{
  char *str;
  char* strValue;
  Eval *evalptr;
}
%start program
%type <evalptr> exp
%type <strValue> PLUS 
%token INTEGER
%token ZERO
%token REALNUM
%token PROGRAM
%token INT
%token REAL
%token BOOL
%token PROCEDURE
%token FUNCTION
%token BEGINN
%token END
%token IF
%token THEN
%token ELSE
%token WHILE
%token DO
%token FOR
%token TO
%token DOWNTO
%token CASE
%token RETURN
%token ANDTHEN
%token ORELSE
%token IDENTIFIER

%token MINUS
%token MULTIPLY
%token DIVISION
%token GREATERTHAN
%token GREATEREQUAL
%token NOTEQUAL
%token EQUAL
%token LESSTHAN
%token LESSEQUAL
%token COMMA
%token SEMICOLON
%token COLON
%token DECLARE
%token OPPAR
%token CPAR
%token FALSE
%token TRUE
%token ERROR
%left COMMA
%left INT BOOL REAL

%left COLON
%left IF_PREC   
%left ELSE
%left ANDTHEN ORELSE
%left PLUS MINUS
%left MULTIPLY DIVISION
%left GREATERTHAN GREATEREQUAL NOTEQUAL EQUAL LESSTHAN LESSEQUAL

%%

program:
    PROGRAM IDENTIFIER M SEMICOLON declist block SEMICOLON {
        printf("\nin program\n"); allSymbolTablePrint( pop(tblptrStack) ); 
    }
    | PROGRAM IDENTIFIER M SEMICOLON block SEMICOLON {
        printf("\nin program\n"); allSymbolTablePrint( pop(tblptrStack) ); 
        printf("this is program");
    }
    ;
M:
    { 
        struct SymbolTable* t = mkTable( NULL , "program");
        push(t, tblptrStack);
    }
;
declist:
    dec
    | declist dec 
    ;
dec : 
    vardec {printf("var deccc");}
    | procdec
    | funcdec
    ;
type : 
    INT {
        currentType=4;
        returnType = (char*) malloc(strlen("INT"));
        strcpy(returnType, "INT");
        printf("this is int");
    }
    | REAL {
        currentType=8;
        returnType = (char*) malloc(strlen("REAL"));
        strcpy(returnType, "REAL");
    }
    |BOOL {
        currentType=1;
        returnType = (char*) malloc(strlen("BOOL"));
        strcpy(returnType, "BOOL");
        printf("this is bool");     
    }
    ;
iddec : 
    IDENTIFIER { enterVar( tempString, currentType , 0 , top(tblptrStack) ); printf("a variable entered:%s\n",tempString); }
    | IDENTIFIER { enterVar( tempString, currentType , 0 , top(tblptrStack) ); printf("a variable entered:%s\n",tempString); } DECLARE {
    printf("this is declare eeee");
    } exp 
    ;
idlist : 
    iddec {printf("this is idlist iddec");}
    | idlist {printf("this is idlist iddec");} COMMA {printf("this is idlist comma");}iddec {printf("this is idlist iddec3333");}
    ;
vardec :
    type idlist SEMICOLON 
    {printf("vardec");}
    ;
procdec :
    PROCEDURE IDENTIFIER NP OPPAR paramdecs CPAR declist block SEMICOLON {
        char* tmpc = top(tblptrStack)->name;
        struct SymbolTable* tmpt = pop(tblptrStack);
        enterProcFunc( tmpc , 0 , "NULL" ,  tmpt , top(tblptrStack) ); 
    }
    | PROCEDURE IDENTIFIER NP OPPAR paramdecs CPAR block SEMICOLON { 
        char* tmpc = top(tblptrStack)->name;
        struct SymbolTable* tmpt = pop(tblptrStack);
        enterProcFunc( tmpc , 0 , "NULL" ,  tmpt , top(tblptrStack) ); 
    }
    ;
NP:
    {
        printf("inside NP\t tempString:%s\n",tempString);
        struct SymbolTable* t = mkTable( top(tblptrStack) , tempString );
        push(t, tblptrStack);
    }
    ;
funcdec :
    FUNCTION IDENTIFIER FN OPPAR paramdecs CPAR COLON type {
        char* tmpc = top(tblptrStack)->name;
        struct SymbolTable* tmpt = pop(tblptrStack);
        enterProcFunc(tmpc , -1 , returnType ,  tmpt , top(tblptrStack) );
    } declist block SEMICOLON
    | FUNCTION IDENTIFIER FN OPPAR paramdecs CPAR COLON type {
        char* tmpc = top(tblptrStack)->name;
        struct SymbolTable* tmpt = pop(tblptrStack);
        enterProcFunc(tmpc , -1 , returnType ,  tmpt , top(tblptrStack) );
    } block SEMICOLON
    ;
FN:
    {
        printf("inside FN\t tempString:%s\n",tempString);
        struct SymbolTable* t = mkTable( top(tblptrStack) , tempString );
        push(t, tblptrStack);
    }
    ;
paramdecs :
    paramdec { printf("paramdecs"); }
    | paramdecs SEMICOLON paramdec { printf("paramdecs\n"); }
    | { printf("paramdecs\n"); }
    ;
paramdec : 
    type paramlist
    ;
paramlist :
    IDENTIFIER 
    | paramlist COMMA IDENTIFIER
    ;
block : 
    BEGINN {printf("hi this is begin");} stmtlist END 
    | stmt 
    ;
stmtlist : 
    stmt 
    | stmtlist SEMICOLON stmt 
    ;
lvalue : 
    IDENTIFIER
    ;
stmt :
    lvalue DECLARE exp 
    | IF exp THEN block %prec IF_PREC
    | IF exp THEN block ELSE block %prec ELSE
    | WHILE exp DO block 
    | FOR lvalue DECLARE exp TO exp DO block 
    | FOR lvalue DECLARE exp DOWNTO exp DO block 
    | CASE exp caseelement END 
    | RETURN exp 
    | exp {printf("stmt exp");}
    ;
exp :

    exp ANDTHEN exp 
    | exp ORELSE exp  
    | exp PLUS {pushS($2);} exp {printf("Rule  \t\t mathlogicExpression -> mathlogicExpression KW_PLUS mathlogicExpression\n");}
    | exp MINUS exp 
    | exp MULTIPLY exp { printf(" RULE FOR MULTIPLY\n");}
    | exp DIVISION exp 
    | OPPAR exp CPAR 
    | boolexp relop boolexp
    | INTEGER {printf("this is integerrrr");}
    | REALNUM 
    | TRUE
    | FALSE 
    | lvalue 
    | IDENTIFIER OPPAR explist CPAR 
    ;
boolexp:
    OPPAR exp CPAR 
    | INTEGER 
    | REALNUM 
    | TRUE
    | FALSE 
    | lvalue 
    | IDENTIFIER OPPAR explist CPAR 
    ;
caseelement : 
    INTEGER COLON block SEMICOLON
    | caseelement INTEGER COLON block SEMICOLON
    ;
explist :
    exp 
    | explist COMMA exp  
    |
    ;
relop :
    GREATERTHAN
    | GREATEREQUAL
    | NOTEQUAL
    | EQUAL
    | LESSTHAN
    | LESSEQUAL
    ;



%%

int t=0;
char num[5];

Eval* codegen(){
  char tmp[2] = "t";
  snprintf(num,5,"%d",t);
  strcat(tmp,num);
  printf("t%d = %s %s %s\n",t,place.stk[place.top-2],place.stk[place.top-1],place.stk[place.top]);
  popS();
  popS();
  popS();
  pushS(tmp);
  t++;
  Eval* e;
  if((e=malloc(sizeof(Eval)))==NULL)
    yyerror("out of memory");
  //e->t_value = tmp;
int i =0;
    while(tmp[i]!='\0')                                                   
     {
            e->t_value[i] = tmp[i];                                                    
            i++;
         }
     e->t_value[i] = tmp[i]; 
  return e;
}

struct SymbolTable* popTop(struct Stack* b ){
    pop(b);
    top(b);
}

int main(){

    display();
    //printf("hi1");
    tblptrStack=createStack();
    tblptrStack->top = NULL;
    //printf("hi2");
    yyin = fopen("input3.txt", "r");
    //printf("hi3");
    yyparse();
    return 0;
}

void yyerror(char* error){
    printf("Error : %s\n", error);
}

这是我的堆栈实现

#define MAXSIZE 1000
struct stack
{
    char stk[MAXSIZE][50];
    int top;
};

typedef struct stack STACK;

STACK place={.top=0};

void pushS(char* num);
void popS(void);
int SP;

void pushS(char* num )
{
       if (place.top == (MAXSIZE - 1))
    {
        printf ("Stack is Full\n");
        return;
    }
    else
    {
        place.top=place.top+1;
        printf("out of while");
        int i=0;
        while(num[i]!='\0')
        {
           place.stk[place.top][i]=num[i];
           i++;
           printf(" inwhile\n");
        }
        printf(" out of while before return\n");
        place.stk[place.top][i]=num[i];

    }
    return;
}
void popS ()
{
    char* num;
    if (place.top == - 1)
    {
        printf ("Stack is Empty\n");

    }
    else
    {
        //num = place.stk[place.top];
        //printf ("poped element is = %sn", place.stk[place.top]);
        place.top = place.top - 1;
    }
    //return(num);
}

void display ()
{
    int i;
    if (place.top == -1)
    {
        printf ("Stack is empty\n");
        return;
    }
    else
    {
        printf ("\n The status of the stack is %d \n",place.top);
        for (i = place.top; i > 0; i--)
        {
        int j = 0;
            //printf ("%s\n", place.stk[i]);
        for (j = 0; place.stk[i][j] != '\0'; j++)
        {
            printf ("%c\n", place.stk[i][j]);
        }

        }
    }
    printf ("\n");
}

这是我得到的错误:

Segmentation fault: 11

我使用的输入是这样的:

Program p1Main;

    Int i1, i2:=
        #-23, i3 := #0-(#3 / (#2-#1));
    Real r1var := #23.003 + i1, r2var;
    Bool b1;
    Bool b2 := (False And Then True).GT.(#1 + #3);

    Procedure p1(Int t1; Bool t2)
        Real t3;

        Function f1() : Int Begin
            For i1 := i2 To #100 Do Begin
                For i2 := i3 Downto #-100 Do Begin
                    #2
                End
            End;
            Return i2
        End;

        Begin
            f1()
        End
    ;

Begin
    p1(#100, #200);
    False;

    If #32 Then
        If i1 .GE. i2 Then Begin
            i1 := i1 + i2;
            i2 := i3
        End Else
            i1 := i3
    ;

    While f1() .NE. #5 Do Begin
        b2
    End;

    Case i1
        #1 : Begin
            True
        End;

        #2 : False;
    End
End
;

我在 macOS 上使用 flex_bison。我尝试过放置 printf 并阅读了所有类似的问题。预先感谢您的帮助。

最佳答案

你给的文件不完整,我无法编译。但是从你的语法文件

exp ANDTHEN exp·
| exp ORELSE exp··
| exp PLUS {pushS($2);}

也许您的意图是 push($1)$2 不是数字,因为 pushS 被声明为 void pushS( char* num ).

关于c - 在 bison 中使用 $2 时出现段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56161956/

相关文章:

java - 关于Java语法中修饰符的问题

c++ - C++是上下文无关的还是上下文相关的?

c - 对于具有预定义值的变量的行为不同

c - 读取Linux内核空间中的字符设备

c - 读写系统调用返回乱码 (C)

c - 尝试递增字母时出现段错误

c - GCC 是否为传递给函数的数组创建 typedef?

c# - 在 C# 中访问 java 编译器的输出

ruby - 您如何为该语言编写编译器?

algorithm - 正则文法产生字符串?