我看到很多“分段错误(核心转储)”错误,但我仍然在努力在我的代码中发现这个错误。 在使用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函数),但它似乎在它之前粉碎。
提前感谢您的帮助。