간체화 된 Java 언어로 자체 제작 된 컴파일러를 실행하려고하는데, 항상 세그먼트 화 오류로 끝납니다. 목표는 추상 구문 트리를 작성하는 것입니다. 또한 valgrind를 사용하여 디버깅을 시도했지만 tool이 내 PC에서 bison과 flex에 문제가있는 것 같습니다. 도와주세요.Flex, Bison 및 Segmentation 폴트 정보
Lexfile :
%{
#include <stdio.h>
#include "abst.h"
#include "yacc.tab.h"
int yylineno;
int column = 0;
int nesting_comments = 0;
int max_comment_level = 0;
int total_comments_number = 0;
void count() {
int i;
for(i = 0; yytext[i] != '\0'; i++){
if(yytext[i] == '\n')
column = 0;
else if(yytext[i] == '\t')
column += 8 - (column % 8);
else
column++;
}
//printf("%s", yytext); Uncomment this Line for printing the input stream
}
void yyerror(char const *s);
%}
DIGIT [0-9]
LETTER [a-zA-Z]
WHITESPACE [ \t\r]
VINT {DIGIT}+
VFLOAT {VINT}+"."{DIGIT}*
VDOUBLE {VFLOAT}E{VINT}
VSTRING \".*\"
COMMENT1 "//".*
%x COMMENT2
COMMENT3 "/""*"([^{"*""/"}])*"*""/"
REL_OP "<"|"<="|"=="|"=>"|">"|"&&"|"||"|"&"|"|"|"!="
ADD_OP "+"|"-"|"%"
MUL_OP "*"|"/"
UNARY_OP "++"|"--"
ASSIGN_OP "+="|"-="|"*="|"/="|"%="
TYPE "boolean"|"int"|"float"|"double"
ID {LETTER}({LETTER}|{DIGIT})*
%%
"if" { count(); return IF; }
"else" { count(); return ELSE; }
"while" { count(); return WHILE; }
"for" { count(); return FOR; }
"read" { count(); return READ; }
"write" { count(); return WRITE; }
"final" { count(); return FINAL; }
{VINT} { count(); yylval.ival = atoi(yytext); return IVALUE; }
{VFLOAT}|{VDOUBLE} { count(); yylval.fval = atof(yytext); return FVALUE; }
{VSTRING} { count(); yylval.identifier = strdup(yytext); return STRING; }
"true" { count(); return TRUE; }
"false" { count(); return FALSE; }
"boolean" { count(); return BOOLEAN; }
"int" { count(); return INT; }
"float" { count(); return FLOAT; }
"double" { count(); return DOUBLE; }
{ID} { count(); yylval.identifier = strdup(yytext); return IDENT; }
{REL_OP} { count(); yylval.ival = getEnum(yytext); return RELOP; }
{ADD_OP} { count(); yylval.ival = getEnum(yytext); return ADDOP; }
{MUL_OP} { count(); yylval.ival = getEnum(yytext); return MULOP; }
{UNARY_OP} { count(); yylval.ival = getEnum(yytext); return UNARYOP; }
"=" { count(); return '='; }
"!" { count(); return '!'; }
"(" { count(); return '('; }
")" { count(); return ')'; }
"[" { count(); return '['; }
"]" { count(); return ']'; }
"{" { count(); return '{'; }
"}" { count(); return '}'; }
"," { count(); return ','; }
";" { count(); return ';'; }
{COMMENT1} {
total_comments_number++;
count();
}
"(*" {
total_comments_number++;
BEGIN(COMMENT2);
printf("(* [BEGIN NESTED %d]\n", nesting_comments++);
count();
}
<COMMENT2>[^*()]* {
printf("%s", yytext); /* Eat other characters */
count();
}
<COMMENT2>"(*" {
printf("(* [BEGIN NESTED %d]\n", nesting_comments);
if(++nesting_comments > max_comment_level) {
max_comment_level = nesting_comments;
}
count();
}
<COMMENT2>"*)" {
printf("\n*) [END NESTED %d]", --nesting_comments);
if (nesting_comments == 0){
BEGIN(INITIAL);
}
count();
}
<COMMENT2>[*()] {
printf("%s", yytext); /* Eat the other characters if it is not a comment delimiter */
count();
}
{COMMENT3} {
total_comments_number++;
count();
}
{WHITESPACE}+ { count(); }
\n { count(); yylineno++; }
. { yyerror("Lex"); }
%%
Yaccfile :
%{
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include "abst.h"
extern char *yytext;
extern int yylineno;
extern FILE *yyin;
extern int column;
extern int nesting_comments;
extern int max_comment_level;
extern int total_comments_number;
int yylex(void);
//int yydebug=1;
node *root;
void yyerror (char const *s){
fprintf (stderr, "%s Error at line %d:%d\n", s, yylineno, column);
fprintf (stderr, "Text was: %s\n", yytext);
exit(EXIT_FAILURE);
}
%}
%union {
char *identifier;
int ival;
float fval;
struct _node *node;
}
%type <identifier> IDENT STRING
%type <ival> IVALUE MULOP RELOP ADDOP UNARYOP
%type <fval> FVALUE
%type <node> program compStmt varDecList varListType type varList ident identArray stmtList
%type <node> statement assignStmt ifStmt elsePart whileStmt forStmt ioStmt ioCall paramList
%type <node> expr simpleExpr term factor mulop addop relop
%token IF ELSE WHILE FOR WRITE READ FINAL
%token IVALUE FVALUE TRUE FALSE STRING
%token BOOLEAN INT FLOAT DOUBLE
%token IDENT
%right UNARYOP '!' '='
%left MULOP ADDOP RELOP
%left '[' ']' '(' ')'
%start program
%%
program
: compStmt { $$ = $1; root = $1;}
;
compStmt
: '{' varDecList stmtList '}' { $$ = new_node(COMP_STMT, (node*[]){ $2, $3, NULL });}
;
varDecList
: varListType varDecList { $$ = new_node(DECLARATION, (node*[]){ $1, $2, NULL }); }
|
;
varListType
: type varList { $$ = new_node(VAR_LIST_TYPE, (node*[]){ $1, $2, NULL }); }
| FINAL type varList { $$ = new_node(VAR_LIST_TYPE, (node*[]){ new_string_node(TYPE, "final") , $2, $3, NULL }); }
;
type
: BOOLEAN { $$ = new_string_node(TYPE, "boolean"); }
| INT { $$ = new_string_node(TYPE, "int"); }
| FLOAT { $$ = new_string_node(TYPE, "float"); }
| DOUBLE { $$ = new_string_node(TYPE, "double"); }
;
varList
: ident ',' varList { $$ = new_node(VAR_LIST, (node*[]){ $1, $3, NULL }); }
| ident ';' { $$ = new_node(VAR_LIST, (node*[]){ $1, NULL }); }
| ident '=' expr ';' { $$ = new_node(VAR_LIST, (node*[]){ $1, $3, NULL }); }
;
ident
: IDENT { $$ = new_string_node(VAR, $1); }
| identArray '[' simpleExpr ']' { $$ = new_node(ARRAY, (node*[]){ $1, $3, NULL }); }
;
identArray
: IDENT { $$ = new_string_node(VAR, $1); }
;
stmtList
: statement stmtList { $$ = new_node(STATEMENT_LIST, (node*[]){ $1, $2, NULL }); }
| statement { $$ = new_node(STATEMENT_LIST, (node*[]){ $1, NULL }); }
;
statement
: assignStmt ';' { $$ = $1; }
| compStmt { $$ = $1; }
| ifStmt { $$ = $1; }
| whileStmt { $$ = $1; }
| forStmt { $$ = $1; }
| ioStmt { $$ = $1; }
;
assignStmt
: ident '=' expr { $$ = new_node(ASSIGN_STMT, (node*[]){ $1, $3, NULL }); }
| ident UNARYOP { $$ = new_node(ASSIGN_STMT, (node*[]){ $1, new_int_node(OP, $2), NULL }); }
;
ifStmt
: IF '(' expr ')' statement elsePart {
if($6->type != NONE){
$$ = new_node(IF_STMT, (node*[]){ $3, $5, $6, NULL });
}
else {
$$ = new_node(IF_STMT, (node*[]){ $3, $5, NULL });
}
}
;
elsePart
: ELSE statement { $$ = $2; }
| { $$ = new_none(); }
;
whileStmt
: WHILE '(' expr ')' statement { $$ = new_node(WHILE_STMT, (node*[]){ $3, $5, NULL }); }
;
forStmt
: FOR '(' assignStmt ';' expr ';' assignStmt ')' statement {
$$ = new_node(FOR_STMT, (node*[]){ $3, $5, $7, $9, NULL });
}
;
ioStmt
: ioCall '(' paramList ')' ';' { $$ = new_node(IOFUNC, (node*[]){ $1, $3, NULL }); }
;
ioCall
: READ { $$ = new_int_node(IOFUNCCALL, 0); }
| WRITE { $$ = new_int_node(IOFUNCCALL, 1); }
;
paramList
: ident ',' paramList { $$ = new_node(PARAM_LIST, (node*[]){ $1, $3, NULL }); }
| STRING ',' paramList { $$ = new_node(PARAM_LIST, (node*[]){ new_string_node(STRING_CONST, $1), $3, NULL }); }
| ident { $$ = new_node(PARAM_LIST, (node*[]){ $1, NULL }); }
| STRING { $$ = new_string_node(STRING_CONST, $1); }
;
expr
: simpleExpr relop simpleExpr { $$ = new_node(EXPR, (node*[]){ $1, $2, $3, NULL }); }
| simpleExpr { $$ = new_node(EXPR, (node*[]){ $1, NULL }); }
;
simpleExpr
: term addop simpleExpr { $$ = new_node(EXPR, (node*[]){ $1, $2 ,$3, NULL }); }
| term { $$ = new_node(EXPR, (node*[]){ $1, NULL }); }
;
term
: factor mulop term { $$ = new_node(EXPR, (node*[]){ $1, $2, $3, NULL }); }
| factor { $$ = new_node(EXPR, (node*[]){ $1, NULL }); }
;
factor
: IVALUE { $$ = new_int_node(INT_CONST, $1); }
| FVALUE { $$ = new_float_node(REAL_CONST, $1); }
| TRUE { $$ = new_int_node(BOOL_CONST, 1); }
| FALSE { $$ = new_int_node(BOOL_CONST, 0); }
| ident { $$ = $1; }
| '!' factor { $$ = new_node(EXPR, (node*[]){ $2, NULL }); }
| '-' factor { $$ = new_node(EXPR, (node*[]){ $2, NULL }); }
| '(' expr ')' { $$ = new_node(EXPR, (node*[]){ $2, NULL }); }
;
mulop
: MULOP { $$ = new_int_node(OP, $1); }
;
addop
: ADDOP { $$ = new_int_node(OP, $1); }
;
relop
: RELOP { $$ = new_int_node(OP, $1); }
;
%%
int main(int argc, char **argv) {
if (argc > 1)
yyin = fopen(argv[1], "r");
else
yyin = stdin;
yyparse();
printf("\nCOMMENT-ANALYSIS:\n");
printf("Total number of comments: %d\n", total_comments_number);
printf("Maximum nested comment level: %d\n", max_comment_level);
printf("\n");
printNode(root);
return 0;
}
좀 구조체와 열거 형을 decleared하는 헤더 :
#ifndef AST_TYPES_H
#define AST_TYPES_H
typedef enum {
COMP_STMT = 0,
ASSIGN,
ASSIGN_STMT,
IF_STMT,
FOR_STMT,
WHILE_STMT,
STATEMENT,
STATEMENT_LIST,
CONST,
VAR,
ARRAY,
VAR_LIST,
TYPE,
EXPR,
SIMPLE_EXPR,
INT_CONST,
REAL_CONST,
BOOL_CONST,
STRING_CONST,
IDENTIFIER,
OP,
IOFUNC,
IOFUNCCALL,
PARAM_LIST,
DECLARATION,
VAR_LIST_TYPE,
NONE,
} node_type;
typedef enum {
PLUS = 0,
MINUS,
MUL,
DIV,
MOD,
LT,
LE,
GT,
GE,
EQ,
NE,
AND,
OR,
PLUSPLUS,
MINUSMINUS,
NOT,
} operator;
typedef union _node_value{
int iValue; /*integer, true, false, compOp, addOp, mulOp */
float fValue; /*number*/
char* identifier; /*identifier*/
/* list of BNF right-hand side symbols of nonterminal type */
struct _node **body;
} node_value;
typedef struct _node {
node_type type;
int size;
node_value value;
} node;
void printNode(node *the_node);
operator getEnum(char *value);
char *printEnum(node_type type);
node* new_none();
node* new_int_node(node_type type, int value);
node* new_float_node(node_type type, float value);
node* new_string_node(node_type type, char *value);
node* new_node(node_type type, node **nodes);
#endif //AST_TYPES_H
headerfunctions을 구현하는 C-파일 :
나는이 같은 프로그램을 컴파일 : 너무 많은
/* This program that implements a few well-known algorithms */
{ int x, y, z;
final int n = 10;
int a[n];
// greatest common divisor
{ read(x, y);
while(x * y != 0)
if(x > y)
x = x - y;
else y = y - x;
if(x == 0)
write("gcd = ", y);
else write("gcd = ", x);
}
// factorial calculation
{ read(x);
y = 1;
for(z = 2; z <= x; z++)
y = y * z;
write(x, " != ", y);
}
// prime number verification
{ int k;
boolean prime;
read(x);
k = 2;
prime = true;
while((k < x/2) && prime) {
if(x % k == 0)
prime = false;
k++;
}
write(x, " is prime is ", prime);
}
// maximum array element
{ int i, max;
for(i = 0; i < n; i++)
read(a[i]);
max = a[0];
for(i = 0; i < n; i++)
if(max > a[i])
max = a[i];
write("max = ", max);
}
// bubble sort
{ boolean k;
float r;
int i;
k = true;
while(k) {
k = false;
for(i = 0; i < n-1; i++)
if(a[i] > a[i+1]) {
b = a[i];
a[i] = a[i+1];
a[i+1] = b;
k = true;
}
}
write("sorted array: ");
for(i = 0; i < n; i++)
write(a[i]);
}
}
주의 시도 line :'if (argc> 0)'가 올바르지 않습니다. argv는 argv []의 첫 번째 엔트리가 프로그램을 호출하는 데 사용 된 경로/이름이 될 것이므로 항상 0보다 커야합니다. 제안 :'if (argc> 1)' – user3629249
내 코드를 살펴 보는 Thx. 그리고 실제로 이것은 잘못된 오류입니다. 그러나 여전히 세분화 오류로 인해 문제가 변경되지는 않습니다. bison이나 flex에 대해 많이 알 필요는 없기 때문에이 오류는 malloc의 잘못된 사용 일 수도 있습니다 ... Java 프로그램은 내 프로그램에 의해 컴파일되어야하는 예제 코드 일뿐입니다. – Harald
: GCD 코드에는'{'braces'}'가 필요합니다. 알고리즘은'-' 연산자로 구현 된 분할 알고리즘처럼 매우 비효율적입니다. 예를 들어, 여러분의 알고리즘은'gcd (2000, 15)'를 계산하기 위해 132 개의 루프를 사용합니다. 반면에 모듈러스 연산자'%'를 사용하는 알고리즘은 1 루프 (2 회 연산은'while' 루프입니다)를 사용합니다. –