2012-01-13 139 views
0

我在這裏新建一個,它是我的第一個問題。Flex Bison編譯器

我必須做一個C++編譯器,我不知道爲什麼我的代碼不工作。 我執行它時遇到分段錯誤。 進出口使用Flex和野牛

 /* Definición de grupos de caracteres */ 
l [a-zA-Z] 
d [0-9] 
n [a-zA-Z_] 
p [a-zA-Z_0-9] 
q [1-9] 
r [0-7] 
s [0-9a-fA-F] 
t [a-zA-Z0-9_{}[]#()<>%:;.?*+-/^&|~!=,'\\ \t\n\0] 

u "todo menos *" 
v "todo menos salto de línea" 

o [\t] 
w [\n] 

%{ 
#include "definiciones.h"  // Carga de constantes auxiliares 
#include "semantico.tab.h" // Carga de constantes de yacc/bison 
#include <string.h> // strcpy() 
#include <stdio.h>  // printf() 
#include <stdlib.h>  
int reservada(char *p); 
%} 

%% 

    /* Variables auxiliares para el analizador léxico */ 
    int salida; // Salida de la función "reservada" y de la función "atoi" 
    int i;  // Iterador 
    int yylineno = 0; 

\n  yylineno++; 

    /* Identificador de entero o palabra reservada */ 
[a-zA-Z_]([a-zA-Z_]|[0-9])* { 
      if (yyleng < MAXCAD) 
       { // El carácter nulo no está incluido en yyleng 
       fprintf(stdout,"%s\n",yytext); 
salida = reservada(yytext); 
       fprintf(stdout,"%s\n",yylval.sValue); 

        return IDENTIFICADOR; 
         } 
      else 
       { 
        fprintf(stdout,"Palabra reservada o identificador de entero demasiado largo\t%4d\t{%s}\n", 
         yylineno,yytext); 
       } 
     } 

    /* Cadena */ 
\"(\\.|[^"])*\"  { 
       strncpy(yylval.sValue,&yytext[1],yyleng-2); 
       yylval.sValue[yyleng-2] = '\0'; // Null-terminated string 
       fprintf(stdout,"%s\n", yytext); 
       return CADENA; 
      } 

    /* Espacios en blanco y tabuladores */ 
[ \t\r]+   ; // Ignoro espacios en blanco 

    /* Error: no es un token válido */ 
.   { 
       fprintf(stdout,"Caracter no valido\t%4d\t{%s}\n", yylineno, yytext); 
      } 

%% 

int reservada(char *p){ 
    char temporal[MAXCAD]; // String temporal 
    int i; // Iterador 
fprintf(stdout,"%d\n", strlen(yylval.sValue)); 
fprintf(stdout,"%d\n", yyleng); 
strcpy(yylval.sValue,temporal);  
fprintf(stdout,"%s\n",temporal); 

    return 0; 
} 
/* Devuelve 1 si no hay que procesar más ficheros 
    Obligatoria su declararación con flex pero no con lex */ 
int yywrap(void){ 
    return 1; 
} 

我都試過了,問題是,我不能更多的複製到yylval.sValue比(yyleng-1)個字符。 發生了什麼?!?! 這是我semantico.y文件

%{ 
/* Librerías auxiliares */ 
#include "definiciones.h" // Carga de constantes auxiliares 
#include <stdio.h>  // printf() 
#include <string.h> // strcpy() 
/* Prototipos */ 
nodeType *crearTypeInt(int value); 
nodeType *crearTypeStr(nodeEnum type, tablaNodos *tabla, char value[MAXCAD]); 
nodeType *buscarLexema(nodeEnum type, tablaNodos *tabla, char value[MAXCAD]); 
nodeType *insertarId(nodeEnum type, char value[MAXCAD]); 
nodeType *insertarIdLocal(nodeEnum type, char value[MAXCAD]); 
nodeType *insertarFuncion(char value[MAXCAD]); 
void iniciarFuncion(char value[MAXCAD], int par); 
void terminarFuncion (void); 
char *nuevoTemporal (void); 
char *nuevaEtiqueta (void); 
void yyerror(char *s); 

/* Variables globales al analizador sintáctico/semántico */ 
extern FILE *yyin; // Viene definida por el lex/flex 
FILE *codInt; // Fichero de salida para el código intermedio 
FILE *codEns; // Fichero de salida para el código ensamblador 
nodeType *auxfor; // Variable auxiliar para el bucle FOR 
nodeType *auxcall; // Variable auxiliar para llamar a funciones 
char *auxif; //Variable auxiliar para IF 
char *auxboolT; // Variable auxiliar para comparaciones booleanas 
char *auxboolF; // Variable auxiliar para comparaciones booleanas 
char *auxforI; // Variable auxiliar para el bucle FOR 
char *auxforF; // Variable auxiliar para el bucle FOR 
tablaNodos *tablaEnteros; // Lista temporal de enteros 
tablaNodos *tablaCadenas; // Lista temporal de cadenas 
char *auxandT; // Variable auxiliar para AND 
char *auxandF; // Variable auxiliar para AND 
int i; // Iterador 
%} 

%union { 
    int iValue; // Para guardar enteros y códigos de operación 
    char sValue[MAXCAD]; // Para guardar lexemas 
    nodeType *nodo; // Para guardar atributos para el analizador semántico 
} 

    /* Tokens */ 
//%token <iValue> PALABRA_RESERVADA 
%token <iValue> ENTERO 
%token <sValue> CADENA 
%token <sValue> IDENTIFICADOR 

/* 
* Punctuation sequences 
*/ 
%token ARROW ARROW_STAR DEC IGUALIGUAL MAYORIGUAL INC MENORIGUAL LOG_AND LOG_OR DISTINTO SHL SHR 
%token ASS_ADD ASS_AND ASS_DIV ASS_MOD ASS_MUL ASS_OR ASS_SHL ASS_SHR ASS_SUB ASS_XOR 
%token DOT_STAR ELLIPSIS CUATROPUNTOS 
/* 
* Reserved words 
*/ 
%token PRIVATE PROTECTED PUBLIC 
%token BOOL CHAR DOUBLE FLOAT INT LONG SHORT SIGNED UNSIGNED VOID WCHAR_T 
%token CLASS ENUM NAMESPACE STRUCT TYPENAME UNION 
%token CONST VOLATILE 
%token AUTO EXPLICIT EXPORT EXTERN FRIEND INLINE MUTABLE REGISTER STATIC TEMPLATE TYPEDEF USING VIRTUAL 
%token ASM BREAK CASE CATCH CONST_CAST CONTINUE DEFAULT DELETE DO DYNAMIC_CAST 
%token ELSE FALSE FOR GOTO IF NEW OPERATOR REINTERPRET_CAST RETURN 
%token SIZEOF STATIC_CAST SWITCH THIS THROW TRUE TRY TYPEID WHILE 
%token COUT CIN 
/* 
* Parametric values. 
*/ 

//%nonassoc CUATROPUNTOS ELSE INC DEC COUT CIN '+' '-' '*' '&' '[' '{' '<' ':' 
//%nonassoc '(' 
%left '=' 
%left '+' 

%type <nodo> expr id_general 
%start translation_unit 
%% 

並且在這之後,我有語法。 正如你所看到的,我聲明瞭我的字符,但是作爲char sValue [MAXCAD]。 MAXCAD在其他文件中聲明...

definiciones.h:

/* --------------------------------------------------------------- */ 

/* DEFINICIÓN DE CONSTANTES */ 

/* Longitud máxima (en caracteres/bytes) de una cadena */ 
#define MAXCAD 32 

/* Valor del mayor entero representable por el ensamblador */ 
#define MAXENT 32768 

/* Tamaño en bytes de un entero del ensamblador usado */ 
#define TAMENT 2 
/* Códigos de palabra reservada */ 
/* 
#define DOT_STAR 105 
#define ARROW_STAR 118 
#define ASS_AND 111 
#define ELLIPSIS 116 

#define SHR 100 
#define SHL 101 
#define LOG_AND 102 
#define LOG_OR 103 
#define INC 104 

#define ASS_SUB 106 
#define ASS_MUL 107 
#define ASS_DIV 108 
#define ASS_MOD 109 
#define ASS_XOR 110 

#define ASS_SHR 112 
#define ASS_SHL 113 
#define ASS_ADD 114 
#define ASS_OR 115 

#define DEC 117 

#define ARROW 119 
#define CIN 120 
#define COUT 121 


#define ASM 1 
#define AUTO 2 
#define BOOL 3 
#define CASE 5 
#define CATCH 6 
#define CHAR 7 
#define CLASS 8 
#define CONST 9 
#define CONST_CAST 10 
#define CONTINUE 11 
#define DEFAULT 12 
#define DELETE 13 
#define DO 14 
#define DOUBLE 15 
#define DYNAMIC_CAST 16 
#define ELSE 17 
#define ENUM 18 
#define EXPLICIT 19 
#define EXPORT 20 
#define EXTERN 21 
#define FALSE 22 
#define FLOAT 23 
#define FOR 24 
#define FRIEND 25 
#define GOTO 26 
#define IF 27 
#define INLINE 28 
#define INT 29 
#define LONG 30 
#define MUTABLE 31 
#define NAMESPACE 32 
#define NEW 33 
#define OPERATOR 34 
#define PRIVATE 35 
#define PROTECTED 36 
#define PUBLIC 37 
#define REGISTER 38 
#define REINTERPRET_CAST 39 
#define RETURN 40 
#define SHORT 41 
#define SIGNED 42 
#define SIZEOF 43 
#define STATIC 44 
#define STATIC_CAST 45 
#define STRUCT 46 
#define SWITCH 47 
#define TEMPLATE 48 
#define THIS 49 
#define THROW 50 
#define TRUE 51 
#define TRY 52 
#define TYPEDEF 53 
#define TYPEID 54 
#define TYPENAME 55 
#define UNION 56 
#define UNSIGNED 57 
#define USING 58 
#define VIRTUAL 59 
#define VOID 60 
#define VOLATILE 61 
#define WCHAR_T 62 
#define WHILE 63 


#define BREAK 4 
#define CUATROPUNTOS 67 




/* Códigos de operador relacional */ 
#define PALABRA_RESERVADA 99 
/* 
#define IGUALIGUAL 84 
#define MENORIGUAL 85 
#define MAYORIGUAL 86 
#define DISTINTO 87 



#define ENTERO 94 
#define CADENA 97 
#define IDENTIFICADOR 98 
#define PALABRA_RESERVADA 99 

/* --------------------------------------------------------------- */ 

/* DEFINICIÓN DE TIPOS */ 

/* Tipos de datos disponibles */ 
typedef enum { typeInt, typeStr, typeIdInt, typeIdStr, typeFun, typeBool } nodeEnum; 
// typeInt: Tipo para constantes de tipo entero 
// typeStr: Tipo para constantes de tipo cadena 
// typeIdInt: Tipo para variables de tipo entero 
// typeIdStr: Tipo para variables de tipo cadena 
// typeFun: Tipo para funciones 
// typeBool: Tipo para variables lógicas (booleanas) 


/* Estructura para las constantes de tipo entero */ 
typedef struct { 
    int value; // Valor de la constante de tipo entera 
} intNodeType; 

/* Estructura para las constantes de tipo cadena y 
    para identificadores de enteros, cadenas y lógicos */ 
typedef struct { 
    char value[MAXCAD]; // Valor de la cadena/lexema 
} strNodeType; 

/* Estructura para el identificador de función */ 
typedef struct { 
    char value[MAXCAD]; // Lexema del identificador 
    int npar; // Número de parámetros 
    nodeEnum par[1]; // Tipo de los parámetros 
} funNodeType; 

/* Estructura para los elementos de la tabla de símbolos */ 
typedef struct nodeTypeTag { 
    nodeEnum type; // Tipo de elemento que contiene el nodo 
    struct tablaNodosIdentificador *tabla; // Tabla en la que se encuentra dicho elemento 
    int desplazamiento; // Desplazamiento del elemento dentro de dicha tabla 
    union { // Distinto según el tipo del elemento 
    intNodeType intn; 
    strNodeType strn; 
    funNodeType funn; 
    }; 
} nodeType; 

/* Nodo intermedio de una lista enlazada de nodos */ 
typedef struct NodoLista{ 
    nodeType *nodo; // Puntero al elemento que estamos almacenando 
    struct NodoLista *siguiente; // Puntero al siguiente nodo 
} Nodo; 

/* Nodo principal de una lista enlazada de nodos */ 
typedef struct tablaNodosIdentificador { 
    int nelementos; // Número de elementos que contiene la lista enlazada 
    int tamano; // Tamaño en bytes de los elementos almacenados en la tabla 
    Nodo *primero; // Puntero al primer nodo de la lista enlazada 
} tablaNodos; 

/* Nodo intermedio de la tabla de símbolos (grupo) */ 
typedef struct GrupoLista{ 
    tablaNodos *nodo; // Puntero al grupo que estamos almacenando 
    struct GrupoLista *siguiente; // Puntero al siguiente nodo 
} Grupo; 

/* Nodo principal de la tabla de símbolos */ 
typedef struct tablaGruposIdentificador { 
    int nelementos; // Número de grupos que contiene la tabla de símbolos 
    Grupo *primero; // Puntero al primer grupo de la tabla de símbolos 
} tablaGrupos; 

/* --------------------------------------------------------------- */ 

/* DEFINICIÓN DE VARIABLES GLOBALES */ 

tablaGrupos *tablaSimbolos; // Tabla de símbolos 
tablaNodos *TSpadre;  // Tabla de símbolos del padre 
tablaNodos *TShijo;  // Tabla de símbolos del hijo 

int contemp; // Contador para crear variables temporales 
int conetiq; // Contador para crear etiquetas 
int param; // Número de parámetros introducidos 
int desparam; // Desplazamiento para insertar los argumentos 

謝謝!

+2

請修剪您所有不必要代碼的問題。 – 2012-01-13 19:19:58

+0

據我所知,如果您在258以下開始令牌編號,可能會遇到問題。因爲您可能會導致與文字字符令牌的衝突。你爲什麼不讓Bison處理令牌編號? – Bort 2012-01-17 16:33:24

回答

1

您不顯示sValue(在%union是.y文件中)的定義是什麼,但這可能是問題所在。它可能是char *sValue;,並且你從不初始化它,所以它是一個垃圾指針,當你試圖解引用它時(與yylval.sValue[..] =),你會崩潰。

編輯

好了,有了更多的代碼,我們可以看到更多的什麼錯誤的。我可以看到兩個明顯的問題與S值處理:

  • 當你看到一個標識符,你從來沒有真正做yytext中任何事情(你將它傳遞給reservada,從未看着它),所以你得到的字符串yylval.sValue是隨機垃圾

  • 當你看到一個字符串時,你會盲目地將它複製到yylval.sValue而不檢查長度,所以如果它超過了32個字符,你會註銷數組的末尾和損壞的東西,可能導致你看到的崩潰。

一般來說,當您遇到分段錯誤時,通常會有一個未初始化或損壞的指針在問題的根源處。使用調試器會告訴你代碼在哪裏崩潰,並且通常會向你顯示不正確的指針。搞清楚爲什麼它不正確可能會很棘手。

+0

我添加了.h文件的定義和.y文件的語法 – AAlferez 2012-01-13 20:33:13

+0

正如您所看到的,我添加了我的文件,以便您可以看到我聲明瞭一切正確。 – AAlferez 2012-01-14 13:45:17