2015-04-19 2 views
1

Я пытаюсь написать парсер для мини-c, используя lex и yacc. Включение однострочных входов очень хорошо работает в случае многолинейных входов, что вызывает ошибку сегментации. Запуск GDB не помог.Ошибка сегментации Lex и Yacc

сл файл

alpha [a-zA-Z] 
digit [0-9] 
%{ 
#include <stdlib.h> 
void yyerror(char *); 
#include "y.tab.h" 
%} 


%% 
[ \t]  ; 
[ \n] { yylineno = yylineno + 1;} 
int return INT; 
float return FLOAT; 
char return CHAR; 
void return VOID; 
double return DOUBLE; 
for  return FOR; 
while return WHILE; 
if return IF; 
else return ELSE; 
printf return PRINTF; 
struct return STRUCT; 
^"#include ".+ ; 
{digit}+  return NUM; 
{alpha}({alpha}|{digit})* return ID; 
"<=" return LE; 
">=" return GE; 
"==" return EQ; 
"!=" return NE; 
">" return GT; 
"<" return LT; 
"."  return DOT; 
\/\/.* ; 
\/\*(.*\n)*.*\*\/ ; 
.  return yytext[0]; 
%% 

су файл

%{ 
#include <stdio.h> 
#include <stdlib.h> 
int yylex(void); 
extern FILE *fp; 
extern FILE *yyin; 
extern int yylineno; 
extern char* yytext; 
%} 
%token INT FLOAT CHAR DOUBLE VOID 
%token FOR WHILE 
%token IF ELSE PRINTF 
%token STRUCT 
%token NUM ID 
%token INCLUDE 
%token DOT 
%right '=' 
%left AND OR 
%left '<' '>' LE GE EQ NE LT GT 
%% 
start: Function 
    | Declaration 
    ; 
/* Declaration block */ 
Declaration: Type Assignment ';' 
    | Assignment ';'  
    | FunctionCall ';' 
    | ArrayUsage ';'  
    | Type ArrayUsage ';' 
    | StructStmt ';'  
    | error 
    ; 
/* Assignment block */ 
Assignment: ID '=' Assignment 
    | ID '=' FunctionCall 
    | ID '=' ArrayUsage 
    | ArrayUsage '=' Assignment 
    | ID ',' Assignment 
    | NUM ',' Assignment 
    | ID '+' Assignment 
    | ID '-' Assignment 
    | ID '*' Assignment 
    | ID '/' Assignment 
    | NUM '+' Assignment 
    | NUM '-' Assignment 
    | NUM '*' Assignment 
    | NUM '/' Assignment 
    | '\'' Assignment '\'' 
    | '(' Assignment ')' 
    | '-' '(' Assignment ')' 
    | '-' NUM 
    | '-' ID 
    | NUM 
    | ID 
    ; 

/* Function Call Block */ 
FunctionCall : ID'('')' 
    | ID'('Assignment')' 
    ; 

/* Array Usage */ 
ArrayUsage : ID'['Assignment']' 
    ; 

/* Function block */ 
Function: Type ID '(' ArgListOpt ')' CompoundStmt 
    ; 
ArgListOpt: ArgList 
    | 
    ; 
ArgList: ArgList ',' Arg 
    | Arg 
    ; 
Arg: Type ID 
    ; 
CompoundStmt: '{' StmtList '}' 
    ; 
StmtList: StmtList Stmt 
    | 
    ; 
Stmt: WhileStmt 
    | Declaration 
    | ForStmt 
    | IfStmt 
    | PrintFunc 
    | ';' 
    ; 

/* Type Identifier block */ 
Type: INT 
    | FLOAT 
    | CHAR 
    | DOUBLE 
    | VOID 
    ; 

/* Loop Blocks */ 
WhileStmt: WHILE '(' Expr ')' Stmt 
    | WHILE '(' Expr ')' CompoundStmt 
    ; 

/* For Block */ 
ForStmt: FOR '(' Expr ';' Expr ';' Expr ')' Stmt 
     | FOR '(' Expr ';' Expr ';' Expr ')' CompoundStmt 
     | FOR '(' Expr ')' Stmt 
     | FOR '(' Expr ')' CompoundStmt 
    ; 

/* IfStmt Block */ 
IfStmt : IF '(' Expr ')' 
     Stmt 
    ; 

/* Struct Statement */ 
StructStmt : STRUCT ID '{' Type Assignment '}' 
    ; 

/* Print Function */ 
PrintFunc : PRINTF '(' Expr ')' ';' 
    ; 

/*Expression Block*/ 
Expr: 
    | Expr LE Expr 
    | Expr GE Expr 
    | Expr NE Expr 
    | Expr EQ Expr 
    | Expr GT Expr 
    | Expr LT Expr 
    | Assignment 
    | ArrayUsage 
    ; 
%% 
#include<ctype.h> 
int count=0; 

int main(int argc, char *argv[]) 
{ 
    yyin = fopen(argv[1], "r"); 

    if(!yyparse()) 
     printf("\nParsing complete\n"); 
    else 
     printf("\nParsing failed\n"); 

    fclose(yyin); 
    return 0; 
} 

yyerror(char *s) { 
    printf("%d : %s %s\n", yylineno, s, yytext); 
} 
+0

Используете ли вы последние версии lex и yacc? –

+0

Да. Сегодня он установлен с терминала. –

+0

это может помочь, если вы представили пример ввода, который не работает – mfro

ответ

0
extern char* yytext; 

Если вы используете Лекса (1) и не прогибается (1), yytext является char[], не char *.

Однако вы, безусловно, должны использовать flex (1), если возможно и доступно. Он превосходил практически момента его выпуска в 1987 году. lex (1) - это просто историческое любопытство.

+0

Да, вы правы. Могу ли я знать, какая разница и почему она работает правильно для однострочного ввода. Не могли бы вы прояснить? –

+0

Вы хотите знать разницу между 'char []' и 'char *'? – EJP

Смежные вопросы