Reputation: 1502
Im new here, its my first question.
I have to make a C++ Compiler and I dont know why my code is not working. I get a Segmentation Fault when I execute it. Im using Flex and 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;
}
I tried everything and the problem is that I cant copy to yylval.sValue more than (yyleng-1) characters. What is going on?!?! This is my semantico.y file
%{
/* 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
%%
and following this, I have the GRAMMAR. As you can see, I declared my char, but as a char sValue[MAXCAD]. MAXCAD is declared in other file...
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
Thank you!
Upvotes: 0
Views: 2278
Reputation: 126478
You don't show what the definition of sValue
(in the %union
is the .y file) is, but that's probably the problem. It's probably char *sValue;
, and you're never initializing it, so its a garbage pointer, and when you try to dereference it (with yylval.sValue[..] =
) you get a crash.
edit
Well, with more code, we can see more of what is going wrong. I can see two obvious problems with sValue handling:
when you see an identifier, you never actually do anything with yytext (you pass it to reservada, which never looks at it), so the string you get in yylval.sValue is random garbage
when you see a string, you blindly copy it to yylval.sValue without checking the length, so if it's longer than 32 characters, you write off the end of the array and corrupt stuff, probably leading to the crash you see.
In general, when you get a Segmentation Fault, there's usually an uninitialized or corrupted pointer somewhere at the root of the problem. Using a debugger will tell you where in the code it is crashing, and will usually show you the incorrect pointer in question. Figuring out exactly why it is incorrect can be tricky.
Upvotes: 1