Lex / Bison中与yyparse()相关的分段错误(核心转储)

时间:2016-12-25 17:57:44

标签: c compiler-construction yacc lex

我看到很多“分段错误(核心转储)”错误,但我仍然在努力在我的代码中发现这个错误。 在使用gdb调试之后,它在我的yacc文件中的main()函数中调用了yyparse()的错误。在程序运行之前,我没有收到与此案相关的任何警告。 我不知道还有什么我做错了,我希望你能帮助我。

这是我的AST lexer文件:

%{
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define YYDEBUG 0
void yyerror(const char *);
extern char* yytext;

%}

%%
[ ]+ {printf("SPACE: start%send\n", yytext);}

boolean {printf("BOOLEAN: %s\n", yytext);yylval =mknode(0,0,"BOOLEAN");return BOOLEAN;}
true {printf("TRUE: %s\n", yytext);yylval =mknode(0,0,"TRUE");return TRUE;}
false {printf("FALSE: %s\n", yytext);yylval =mknode(0,0,"FALSE");return FALSE;}
procedure {printf("FUNCTION: %s\n", yytext);yylval =mknode(0,0,"FUNCTION");return FUNCTION;}
float {printf("FLOAT: %s\n", yytext);yylval =mknode(0,0,"FLOAT");return FLOAT;}
char {printf("CHAR: %s\n", yytext);yylval =mknode(0,0,"CHAR");return CHAR;}
integer {printf("INT: %s\n", yytext);yylval =mknode(0,0,"INT");return INT;}
string {printf("STRING: %s\n", yytext);yylval =mknode(0,0,"STRING");return STRING;}
intptr {printf("INTPTR: %s\n", yytext);yylval =mknode(0,0,"INTPTR");return INTPTR;}
charptr {printf("CHARPTR: %s\n", yytext);yylval =mknode(0,0,"CHARPTR");return CHARPTR;}
if {printf("COND: %s\n", yytext);yylval =mknode(0,0,"COND");return COND;}
else {printf("BLOCK: %s\n", yytext);yylval =mknode(0,0,"BLOCK");return BLOCK;}
while {printf("WHILE_COND: %s\n", yytext);yylval =mknode(0,0,"WHILE_COND");return WHILE_COND;}
var {printf("VARIABLE: %s\n", yytext);yylval =mknode(0,0,"VARIABLE");return VARIABLE;}
return {printf("RETURN: %s\n", yytext);yylval =mknode(0,0,"RETURN");return RETURN;}
null {printf("NL: %s\n", yytext);yylval =mknode(0,0,"NL");return NL;}
intarray  {printf("KEY_INTARRAY: %s\n", yytext);yylval =mknode(0,0,"KEY_INTARRAY");return KEY_INTARRAY;}

\&\& {printf("AND: %s\n", yytext);yylval =mknode(0,0,"AND");return AND;}
\/ {printf("DIVISION_OP: %s\n", yytext);yylval =mknode(0,0,"DIVISION_OP");return DIVISION_OP;}
\/\%.*\%\/ {printf("COMMENT: %s\n", yytext);yylval =mknode(0,0,"COMMENT");return COMMENT;}
\= {printf("ASSIGN: %s\n", yytext);yylval =mknode(0,0,"ASSIGN");return ASSIGN;}
\=\= {printf("EQUAL: %s\n", yytext);yylval =mknode(0,0,"EQUAL");return EQUAL;}
\> {printf("BIGGER_THEN: %s\n", yytext);yylval =mknode(0,0,"BIGGER_THEN");return BIGGER_THEN;}
\>\= {printf("BIGGER_OR_EQUAL: %s\n", yytext);yylval =mknode(0,0,"BIGGER_OR_EQUAL");return BIGGER_OR_EQUAL;}
\< {printf("SMALLER_THEN: %s\n", yytext);yylval =mknode(0,0,"SMALLER_THEN");return SMALLER_THEN;}
\<\= {printf("SMALLER_OR_EQUAL: %s\n", yytext);yylval =mknode(0,0,"SMALLER_OR_EQUAL");return SMALLER_OR_EQUAL;}
\- {printf("MINUS: %s\n", yytext);yylval =mknode(0,0,"MINUS");return MINUS;}
\! {printf("LOGICAL_NOT: %s\n", yytext);yylval =mknode(0,0,"LOGICAL_NOT");return LOGICAL_NOT;}
\!\= {printf("NOT_EQUAL: %s\n", yytext);yylval =mknode(0,0,"NOT_EQUAL");return NOT_EQUAL;}
\|\| {printf("OR: %s\n", yytext);yylval =mknode(0,0,"OR");return OR;}
\| {printf("ABS: %s\n", yytext);yylval =mknode(0,0,"ABS");return ABS;}
\+ {printf("PLUS: %s\n", yytext);yylval =mknode(0,0,"PLUS");return PLUS;}
\* {printf("MUL: %s\n", yytext);yylval =mknode(0,0,"MUL");return MUL;}
\& {printf("ADDRESS_OF: %s\n", yytext);yylval =mknode(0,0,"ADDRESS_OF");return ADDRESS_OF;}
\^ {printf("DEREFERANCE: %s\n", yytext);yylval =mknode(0,0,"DEREFERANCE");return DEREFERANCE;}
\( {printf("L_BRACKET: %s\n", yytext);yylval =mknode(0,0,"L_BRACKET");return L_BRACKET;}
\) {printf("R_BRACKET: %s\n", yytext);yylval =mknode(0,0,"R_BRACKET");return R_BRACKET;}
\[ {printf("L_STRING_INDEX: %s\n", yytext);yylval =mknode(0,0,"L_STRING_INDEX");return L_STRING_INDEX;}
\] {printf("R_STRING_INDEX: %s\n", yytext);yylval =mknode(0,0,"R_STRING_INDEX");return R_STRING_INDEX;}
\; {printf("EOS: %s\n", yytext);yylval =mknode(0,0,"EOS");return EOS;}
\{ {printf("OB: %s\n", yytext);yylval =mknode(0,0,"OB");return OB;}
\} {printf("CB: %s\n", yytext);yylval =mknode(0,0,"CB");return CB;}
\, {printf("COMMA: %s\n", yytext);yylval =mknode(0,0,"COMMA");return COMMA;}
\: {printf("VAR_DEC: %s\n", yytext);yylval =mknode(0,0,"VAR_DEC");return VAR_DEC;}
\_ {printf("UNDERSCORE: %s\n", yytext);yylval =mknode(0,0,"UNDERSCORE");return UNDERSCORE;}
\|[\-]*[0-9]+\| {printf("ABSULUTE_VALUE_OF_INT: %s\n", yytext);yylval =mknode(0,0,"ABSULUTE_VALUE_OF_INT");return ABSULUTE_VALUE_OF_INT;}
\|[a-zA-Z0-9]+\| {printf("DECLARED_LENGTH_OF_STRING: %s\n", yytext);yylval =mknode(0,0,"DECLARED_LENGTH_OF_STRING");return DECLARED_LENGTH_OF_STRING;}

[a-zA-Z]+[_]*[a-zA-Z0-9]* {printf("IDENTIFIER: %s\n", yytext);yylval =mknode(0,0,"IDENTIFIER");return IDENTIFIER;}
[\"][a-zA-Z0-9]+[\"] {printf("STRING_TYPE: %s\n", yytext);yylval =mknode(0,0,"STRING_TYPE");return STRING_TYPE;}
[\'].[\'] {printf("CHAR_TYPE: %s\n", yytext);yylval =mknode(0,0,"CHAR_TYPE");return CHAR_TYPE;}
[0-9]+[\.][0-9]+ {printf("FLOAT_CONST: %s\n", yytext);yylval =mknode(0,0,"FLOAT_CONST");return FLOAT_CONST;}
[\-][0-9]+[\.][0-9]+ {printf("FLOAT_CONST: %s\n", yytext);yylval =mknode(0,0,"FLOAT_CONST");return FLOAT_CONST;}
0|[1-9]+[0-9]* {printf("INTEGER_CONST: %s\n", yytext);yylval =mknode(0,0,"INTEGER_CONST");return INTEGER_CONST;}
[\-][1-9]+[0-9]* {printf("INTEGER_CONST: %s\n", yytext);yylval =mknode(0,0,"INTEGER_CONST");return INTEGER_CONST;}
0[x|X][0-9]+[a-fA-F0-9]*[a-fA-F0-9]* {printf("HEX_NUMBER: %s\n", yytext);yylval =mknode(0,0,"HEX_NUMBER");return HEX_NUMBER;}
[0][^xX][1-7]+[0-7]* {printf("OCTAL_NUMBER: %s\n", yytext);yylval =mknode(0,0,"OCTAL_NUMBER");return OCTAL_NUMBER;}
[0|1]+[b] {printf("BINARY_NUMBER: %s\n", yytext);yylval =mknode(0,0,"BINARY_NUMBER");return BINARY_NUMBER;}


\^\^ {printf("SYNTAX_ERROR: %s\n", yytext);yylval =mknode(0,0,"SYNTAX_ERROR");return SYNTAX_ERROR;}
[\']..+[\'] {printf("SYNTAX_ERROR: %s\n", yytext);yylval =mknode(0,0,"SYNTAX_ERROR");return SYNTAX_ERROR;}
\&[0-9]* {printf("LINKER_ERROR: %s\n", yytext);yylval =mknode(0,0,"LINKER_ERROR");return LINKER_ERROR;}
\&[a-zA-Z]+[\+|\-|\*|\/][a-zA-Z]+ {printf("LINKER_ERROR: %s\n", yytext);yylval =mknode(0,0,"LINKER_ERROR");return LINKER_ERROR;}
\&[^[[\"][a-zA-Z0-9]+[\"]\[0-9]+\]]] {printf("LINKER_ERROR: %s\n", yytext);yylval =mknode(0,0,"LINKER_ERROR");return LINKER_ERROR;}

[a-zA-Z]+[=][a-zA-Z]+[=] {printf("SYNTAX_ERROR: %s\n", yytext);yylval =mknode(0,0,"SYNTAX_ERROR");return SYNTAX_ERROR;}
\"\m\a\i\n\(\)\" {printf("CASE_SENSETIVE_ERROR: %s\n", yytext);yylval =mknode(0,0,"CASE_SENSETIVE_ERROR");return CASE_SENSETIVE_ERROR;}
%%

int yywrap(void) {
    return 1;
}

这是我的AST yacc文件:

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

int yylex(void);
void yyerror(const char *);

typedef struct node{
        char *token;
    //int line_number;
        struct node *left;
        struct node *right;
} node;

#define YYSTYPE struct node *

node *mknode(node *left, node *right, char *token);
void printtree(node *tree);

%}

%error-verbose

%start program

%token BOOLEAN TRUE FALSE FUNCTION FLOAT CHAR INT STRING INTPTR CHARPTR DECL
%token L_BRACKET COND WHILE_COND BLOCK VARIABLE RETURN OB CB EOS FUNC_DECL_ERROR
%token AND DIVISION_OP COMMENT ASSIGN EQUAL BIGGER_THEN BIGGER_OR_EQUAL DECL_ERROR
%token SMALLER_THEN SMALLER_OR_EQUAL MINUS LOGICAL_NOT NOT_EQUAL OR PLUS DECL_LIST
%token ADDRESS_OF SEMANTIC_ERROR DEREFERANCE SYNTAX_ERROR PARAMETER_LIST KEY_INTARRAY
%token R_BRACKET L_STRING_INDEX R_STRING_INDEX COMMA VAR_DEC NL TYPE_MISMATCH_ERROR
%token UNDERSCORE ABSULUTE_VALUE_OF_INT DECLARED_LENGTH_OF_STRING IDENTIFIER
%token STRING_TYPE CHAR_TYPE FLOAT_CONST INTEGER_CONST HEX_NUMBER OCTAL_NUMBER
%token BINARY_NUMBER CASE_SENSETIVE_ERROR LINKER_ERROR RETURN_ERROR ABS

%left OR
%left AND
%left EQUAL NOT_EQUAL
%left BIGGER_THEN BIGGER_OR_EQUAL SMALLER_THEN SMALLER_OR_EQUAL
%left PLUS MINUS
%left MUL DIVISION_OP

%right ASSIGN
%right LOGICAL_NOT 

%nonassoc BLOCK

%%

program : functions { printtree($1); }
        ;

functions : functions function { $$=mknode($1,$2,"");}
        | /*none*/ { $$=0; }
        ;

function   : FUNCTION IDENTIFIER L_BRACKET f_params R_BRACKET RETURN type OB body CB
               {$1->left=$2; $1->right=$9; $$=$1; }
           ;

body       : var_decls func_decls stmts ret_stmt  
              {$1->left=$2; $1->right=$3; $3->left=$4; $$=$1;}
           ;

nest_block : stmts { $$ = $1; }
       ;

f_params   : f_params_  { $$ = $1; }
           |  /*none*/ { $$=0; }
           ;

f_params_  : param { $$ = $1; }
           ;

param      :  IDENTIFIER COMMA f_params_ { $1->left=$3; $$=$1; } | IDENTIFIER VAR_DEC type { $1->left=$3; $$=$1; } 
           ;

var_decls  : var_decls var_decl {$1->left=$2; $$ = $1;}
           | /*none*/ { $$=0; }
           ;

var_decl   : VARIABLE var_list VAR_DEC atype EOS {$1->left=$2; $1->right=$4; $$=$1;}
           ;

var_list   : var_list COMMA IDENTIFIER {$1->left=$3; $$=$1;}
           | IDENTIFIER {$$=$1;}
           ;

type       : BOOLEAN {$$=$1;}
           | INT {$$=$1;}
           ;

atype      : type {$$ = $1;}
           | KEY_INTARRAY L_STRING_INDEX integer R_STRING_INDEX {$$=$3;}
           ;

func_decls : func_decls function {$1->left=$2; $$ = $1;}
           | /*none*/ { $$=0; }
           ;

stmts      : stmts stmt {$1->left=$2; $$ = $1;}
           | /*none*/ { $$=0; }
           ;

stmt       : assignment {$$ = $1;}
           | fct_call {$$ = $1;}
           | COND L_BRACKET expr R_BRACKET OB nest_block CB {$$=mknode($3,$6,"");}
           | COND L_BRACKET expr R_BRACKET OB nest_block CB BLOCK OB nest_block CB      
                                    {$5->left=$1; $5->right=$6; $1->left=$2; $2->left=$3;$2->right=$4; $6->left=$7; $$=$1;}
           ;

opt_assign : assignment {$$ = $1;}
           | /*none*/ { $$=0; }
           ;

ret_stmt   : RETURN expr EOS {$$=$2; }
           ;

assignment : IDENTIFIER ASSIGN expr EOS { $2->left=$1; $2->right=$3; $$=$2;/*$$=mknode($1,$3,"");*/}
       | IDENTIFIER L_STRING_INDEX expr R_STRING_INDEX ASSIGN expr EOS {$1->left=$2; $1->right=$3; $3->left=$4; $3->right=$5; $5->left=$6; $5->right=$7; $$=$1;}
           ;

fct_call   : IDENTIFIER ASSIGN IDENTIFIER L_BRACKET expr_list R_BRACKET EOS     
                {$2->left=$1; $2->left=$3; $$=mknode($2,$5,"");}
       | IDENTIFIER L_STRING_INDEX expr R_STRING_INDEX ASSIGN IDENTIFIER L_BRACKET expr_list R_BRACKET EOS
                {$2->left=$1; $2->right=$3; $4->left=$6; $4->right=$8; $$=mknode($2,$4,"");}
           ;

expr_list  : expr_list_ expr { $1->left=$2; $$ = $1; }
       | /*none*/ { $$=0; }
       ;

expr_list_ : expr_list_ expr COMMA  { $1->left=$2; $$ = $1; }
       | /*none*/ { $$=0; }
       ;

expr       : expr PLUS expr  {$$=mknode($1,$3,"+");}
           | expr MINUS expr {$$=mknode($1,$3,"-");}
           | expr MUL expr  {$$=mknode($1,$3,"*");}
           | expr DIVISION_OP expr   {$$=mknode($1,$3,"/");}
           | expr AND expr {$$=mknode($1,$3,"||");}
           | expr OR expr  {$$=mknode($1,$3,"+");}
           | expr NOT_EQUAL expr  {$$=mknode($1,$3,"!=");}
           | expr EQUAL expr  {$$=mknode($1,$3,"==");}
           | expr BIGGER_OR_EQUAL expr {$$=mknode($1,$3,">=");}
           | expr BIGGER_THEN expr {$$=mknode($1,$3,">");}
           | expr SMALLER_THEN expr {$$=mknode($1,$3,"<");}
           | expr SMALLER_OR_EQUAL expr {$$=mknode($1,$3,"<=");}
           | LOGICAL_NOT expr {$$=$2;}
           | MINUS expr  {$$=$2;} %prec LOGICAL_NOT
           | literal {$$ = $1;}
           | IDENTIFIER {$$ = $1;}
           | IDENTIFIER L_STRING_INDEX expr R_STRING_INDEX {$$=mknode($1,$3,"");}
           | L_BRACKET expr R_BRACKET {$$ = $2;}
           | ABS expr ABS { $$=$2; }
           ;

literal    : integer {$$=$1;}
           | TRUE    {$$=$1;}
           | FALSE   {$$=$1;}
           ;

integer    : INTEGER_CONST {$$=$1;}
           | HEX_NUMBER  {$$=$1;}
           | BINARY_NUMBER  {$$=$1;}
           | OCTAL_NUMBER {$$=$1;}
           ;

%%
#include "lex.yy.c"

int main (void) {yyparse(); return 0;}

node *mknode(node *left, node *right, char *token)
{

 node *newnode = (node *)malloc(sizeof(node));
 char *newstr = (char *)malloc(sizeof(token)+1);
 strcpy(newstr,token);
 newnode->left = left;    
 newnode->right = right;
 newnode->token = newstr;
 return newnode;
}

void printtree(node *tree){

  if(!tree)
    return;

  if (tree->left || tree->right)
    printf("(");

  printf(" %s ", tree->token);

  if (tree->left)
    printtree(tree->left);
  if (tree->right)
    printtree(tree->right);

  if (tree->left || tree->right)
    printf(")");
}

extern int yylineno;

void yyerror(const char *s) {
    fprintf(stderr, "line %d: %s\n", yylineno, s);
}

注意在程序遍历所有正确的语法之后出现错误。然后我需要预先打印树(这是printtree函数),但它似乎在它之前粉碎。

提前感谢您的帮助。

0 个答案:

没有答案