Flex Bison Compiler - PullRequest
       45

Flex Bison Compiler

0 голосов
/ 13 января 2012

Я новичок здесь, это мой первый вопрос.

Мне нужно сделать компилятор C ++, и я не знаю, почему мой код не работает.Я получаю ошибку сегментации, когда выполняю ее.Я использую Flex и Bison

        /* 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.sVueue больше, чем (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, но как 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

Спасибо!

1 Ответ

1 голос
/ 14 января 2012

Вы не показываете, каково определение sValue%union есть файл .y), но это, вероятно, проблема.Вероятно, это char *sValue;, и вы никогда не инициализируете его, поэтому это указатель мусора, и когда вы пытаетесь разыменовать его (с yylval.sValue[..] =), вы получаете сбой.

edit

Ну, с большим количеством кода, мы можем видеть больше того, что идет не так.Я вижу две очевидные проблемы с обработкой sValue:

  • когда вы видите идентификатор, вы фактически никогда ничего не делаете с yytext (вы передаете его в reservada, который никогда не смотрит на него), поэтомустрока, которую вы получаете в yylval.sValue, является случайным мусором

  • когда вы видите строку, вы слепо копируете ее в yylval.sValue без проверки длины, поэтому, если она длиннее 32 символов,вы списываете конец массива и повреждаете вещи, что, вероятно, приводит к сбою, который вы видите.

В общем, когда вы получаете ошибку сегментации, обычно где-то есть неинициализированный или поврежденный указательв корне проблемы.Использование отладчика покажет вам, где в коде происходит сбой, и, как правило, покажет неверный указатель, о котором идет речь.Выяснить, почему это неправильно, может быть сложно.

...