2014-09-26 39 views
-1

我想解析像'x = 1;'的语句使用弯曲和野牛。为此,我创建一个符号表来存储'x'和它的值1.因此,下一次当解析器看到像'x = 2'这样的语句时它会将符号表中x的值更新为2. 现在我的野牛和flex代码对于单个字母变量(例如:x,y,a,b,c等)可以正常工作。但是,当我尝试使用字符串变量(多个字符)时,程序将引发分段错误。我不完全了解到底发生了什么问题以及在哪里。下面是抛出Seg Fault的代码。如何扫描Flex中的字符串,然后解析它在野牛

这是flex.l文件:

%{ 
#include <stdio.h> 
#include "calc.tab.h" 
%} 

digit ([0-9]) 
id  ([a-z]) 



%% 

"print"  {  return(TOK_PRINTLN);} 

"prints" { return(TOK_PRINTSTR);} 

"main()" {return(TOK_MAIN);} 
"{"   {return(TOK_LBRACE);} 
"}"   {return(TOK_RBRACE);} 

{digit}+ { 
     sscanf(yytext, "%d", &yylval); 
     return TOK_NUM; 
     } 
"("  { return(TOK_LPARAN);} 
")"  { return(TOK_RPARAN);} 
";" { return(TOK_SEMICOLON); } 

"+" { return(TOK_ADD); } 
"+=" { return(TOK_ADDEQ); } 
"-" { return(TOK_SUB); } 
"-=" { return(TOK_SUBEQ); } 
"=" { return(TOK_EQUAL); } 
{id}+ { 
    sscanf(yylval.character,"%s",strdup(yytext)); 
    return (TOK_ID); 
} 
[ \n] {} 

. {printf("Invalid character '%c', ignored\n", 
      yytext[0]); 
      printf("Line Number %d\n", yylineno); 
    } 

%% 

这是野牛代码.Y文件:

%{ 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

typedef struct Node 
{ 
    char *sym; //changed 
    int val; 
    struct Node *next; 
}SymTable; 

SymTable *Head; 

int symExists(char *c) //changed 
{ 
    SymTable *tmp = malloc(sizeof(SymTable)); 
    tmp = Head; 
    while(tmp != NULL) 
    { 
     if(!(strcmp(tmp->sym,c))) //changed 
     return 1; 
     tmp = tmp->next; 
    } 
    return 0; 
} 

SymTable *getNodeOf(char *c)//changed 
{ 
    SymTable *tmp = malloc(sizeof(SymTable)); 
    tmp = Head; 
    while(tmp != NULL) 
    { 
     if(!strcmp(tmp->sym,c))//changed 
     return tmp; 
     tmp = tmp->next; 
    } 
    return NULL; 
} 


void Insert(char *sym,int val)//changed 
{ 
    //printf("%s\n",sym); 
    //int i = getstrlen(sym); 

    SymTable *tmp =(SymTable*) malloc(sizeof(SymTable)); 
    //printf("Here 1\n"); 
    //tmp->sym = (char *) malloc(50*sizeof(char)); 
    //printf("Here 2\n"); 
    /*tmp->sym=sym;*/strcpy(tmp->sym,sym);//changed 
    tmp->val = val; 

    if(Head == NULL) 
    { 
     tmp->next = NULL; 
     Head = tmp; 
    } 
    else 
    { 
     if(symExists(sym))//changed 
     { 
      tmp = getNodeOf(sym);//changed 
      tmp->val = val; 
     } 
     else 
     { 
      tmp->next = Head; 
      Head = tmp; 
     } 
    } 
    fprintf(stdout,"val:%d sym: %s\n",tmp->val,tmp->sym); //changed 

} 

int getTokIdVal(char *sym) //changed 
{ 
    SymTable *tmp = malloc(sizeof(SymTable)); 
    tmp = Head; 
    while(tmp!=NULL) 
    { 
     if(!strcmp(tmp->sym,sym)) //changed 
     return tmp->val; 
     tmp= tmp->next; 
    } 
    return 0; 
} 

int eval(int a,int b,char c,char *sym) //changed 
{ 

    switch(c) 
    { 
     case '+': 
     return a+b; 
     break; 
     case '-': 
     return a-b; 
     break; 
     case 'n': 
     return a; 
     break; 
     case '=': 
     Insert(sym,a); 
     break; 
     case 'm': 
     return -a; 
     break; 

    } 
    return 0; 
} 


%} 

%token TOK_SEMICOLON TOK_ADD TOK_SUB TOK_MUL TOK_DIV TOK_NUM TOK_PRINTLN TOK_EQUAL TOK_PRINTSTR TOK_QUOTE TOK_LPARAN TOK_RPARAN TOK_ADDEQ TOK_SUBEQ TOK_MAIN TOK_LBRACE TOK_RBRACE 

%union{ 
     int int_val; 
     char *character;//changed 
} 

%token <character> TOK_ID//changed 


/*%type <int_val> expr TOK_NUM*/ 
%type <int_val> expr TOK_NUM 



%left TOK_ADD TOK_SUB 
%left TOK_MUL TOK_DIV 

%% 



stmt: 
    |stmt expr_stmt 
; 

expr_stmt: 
     expr TOK_SEMICOLON 
     | TOK_PRINTLN expr TOK_SEMICOLON 
     { 
      fprintf(stdout, "the value is %d\n", $2); 
     } 

; 

expr: 
    expr TOK_ADD expr 
     { 
      $$ = eval($1,$3,'+',NULL); 
     } 
    | TOK_ID TOK_ADDEQ expr 
     { 
      $$ = eval(getTokIdVal($1),$3,'+',NULL); 
      Insert($1,$$); 

     } 
    | expr TOK_SUB expr 
     { 
      $$ = eval($1,$3,'-',NULL); 
     } 
    | TOK_ID TOK_SUBEQ expr 
     { 
      $$ = eval(getTokIdVal($1),$3,'-',NULL); 
      Insert($1,$$); 

     } 
    | TOK_NUM 
     { 
     $$ = eval($1,0,'n',NULL); 
     } 
    | TOK_ID TOK_EQUAL expr 
     { 
      $$ = eval($3,0,'=',$1); 

     } 
    | TOK_ID 
     { 
     $$ = getTokIdVal($1); 
     } 
    | TOK_LPARAN TOK_SUB expr TOK_RPARAN 
    { 
     $$ = eval($3,0,'m',NULL); 
    } 

; 



%% 


int yyerror(char *s) 
{ 
    printf("%s\n", s); 

    return 0; 
} 

int main() 
{ 
    yyparse(); 

    return 0; 
} 

回答

1

你为你的符号表链表代码是完全炒 - 这代码(它出现在多个地方)是无稽之谈:

SymTable *tmp = malloc(sizeof(SymTable)); 
tmp = Head; 

因为它为对象分配空间,但随后立即overw仪表返回的指针,所以内存泄漏。在符号表中搜索时,不需要分配任何内存,并且Insert只需要在符号尚未存在时分配。阅读基本教程用C链表,如this one

这种说法是无稽之谈,以及:

sscanf(yylval.character,"%s",strdup(yytext)); 

它试图从没有被设置为任何事情yylval.character阅读并覆盖符号你正在尝试返回。您可能只需要:

yylval.character = strdup(yytext); 

这里。

+0

谢谢克里斯。 – Sandeep 2014-09-27 03:36:33