CI-1322 Autómatas y compiladores
Realizado por :
Sharon Amador Vargas A10218
Roberto Hernández Montoya A11727
Formato
del archivo de entrada
Los lenguajes de programación tienen reglas que prescriben la estructura sintáctica de programas bien formados. Se puede describir la sintaxis de las construcciones de los lenguajes de programación por medio de gramáticas independientes del contexto. El analizador sintáctico se encarga de comprobar si una cadena que sale del analizador léxico puede ser generada por la gramática del lenguaje fuente.
Existen herramientas de software que se encargan de
generar analizadores sintácticos. En esta tarea se ejemplifica el uso de esos
programas utilizando Bison , el cual recibe una gramática independiente
del contexto, en este caso para un dialecto de Prolog.
Es posible combinar este programa con el analizador léxico creado con FLEX, que fue ejemplificado en la tarea # 5.
Modificar
la solución de la sexta tarea para que
use un analizador sintáctico obtenido con Yacc/Bison.
El
problema se soluciona creando un analizador sintáctico para la gramática de la
tarea pasada, con el programa Bison, al cual le corresponde el archivo ‘nombre_de_archivo.tab.c’.
Este archivo se incorpora con el archivo del analizador léxico generado en la
tarea anterior.
R
Crear un analizador sintáctico con la herramienta
Bison.
R
Modificar la tarea anterior para que use el método yyparse(),
definido en el analizador sintáctico.
R
La gramática de la tarea anterior no debe tener
errores.
La principal herramienta que se usó fue el generador de analizadores sintácticos Bison.
Como se puede observar en la figura 1, Bison recibe en el archivo de entrada la especificación de una gramática independiente del contexto y produce una función en lenguaje C que reconoce las instancias correctas de la gramática.
Especificación en YACC
Algo.y
y.tab.c a.out
|
Un
archivo de gramática de Bison consta de cuatro partes:
%{
Declaraciones en C
%}
Declaraciones en Bison
%%
Reglas Gramaticales
%%
Código C adicional
Las declaraciones
en C son definiciones de macros y declaraciones de funciones y variables que se
utilizan en las acciones de las reglas gramaticales.
Para el
programa en Prolog, el archivo de entrada fue:
%{
#include
<ctype.h>
#include
<stdio.h>
#include "p7.tab.h"
%}
/* declaraciones en Bison */
%token NUM
%token PABRE
%token PCIERRA
%token
ID
%token
NL
%token
IS
%token
OP_AS
%token
FINLI
%token
COMA
%token
RAYA
%token
ADMI
%token
PABREC
%token
PCIERRAC
%left
OP_SUM
%left
OP_MUL
/* Reglas gramaticales*/
%%
lista_conj: lista_conj conj
| conj
;
conj: prop OP_AS lista_prop FINLI
;
lista_prop: lista_prop COMA prop
| prop
;
prop : ID PABRE entre PCIERRA
| operacion
| ADMI
| NL
;
entre : param
| arreglo
;
arreglo : PABREC param PCIERRAC
;
param: param COMA operacion
| param
COMA expn
| operacion
| expn
;
operacion : ID IS expr
;
expr : expr OP_SUM termino
| termino
;
termino: termino OP_MUL factor
| factor
;
expn : term
| RAYA
;
factor: term
| PABRE
expr PCIERRA
;
term : NUM
| ID
;
%%
yyerror
(s) /* Called by yyparse on error */
char *s;
{
printf ("%s\n", s);
}
main ()
{
yyparse ();
}
¿ Cómo utilizar Flex con Bison ?
La función yylex() generada por Flex; reconoce
tokens y se los devuelve al analizador. Bison no implementa tal función, pero la
ocupa para yyparse(). Por lo tanto utilizamos Flex para generar la función y la
utilizamos en Bison.
Para este
caso el archivo de entrada para Flex fue:
%{
#include
"p7.tab.h"
%}
%option
noyywrap
delim [ \t\n]
blancos {delim}+
letra [A-Za-z]
admir [!]
digito [0-9]
id {letra}({letra}|{digito})*
numero {digito}+
%%
{blancos} { /*no realiza accion*/}
is
{ return(IS);}
nl
{ return(NL);}
eof
{ return(0);}
{id}
{ return(ID); }
{numero}
{ return(NUM);}
"."
{ return(FINLI);}
":-"
{ return(OP_AS);}
"+"
{ return(OP_SUM); }
"-"
{ return(OP_SUM); }
"*"
{ return(OP_MUL); }
"/"
{ return(OP_MUL); }
"("
{ return(PABRE); }
")"
{ return(PCIERRA); }
"["
{ return(PABREC); }
"]"
{ return(PCIERRAC); }
","
{ return(COMA); }
"_" { return(RAYA); }
{admir} { return(ADMI); }
%%
Función de yyparse()
Para
iniciar el análisis, se debe llamar a yyparse(). Esta función se encarga
de leer tokens y ejecutar acciones.
Retorna cuando encuentra el final de archivo o cuando encuentra un error de sintaxis
del que no puede recuperarse.
Visual C++ 6.0 Microsoft Compiler.
Se proveen tres archivos necesarios
para la compilación del programa:
P7.tab.c , p7.tab.h y lex.yy.c.
Para compilar el programa se debe
crear un nuevo proyecto de consola en Visual C++ y luego agregar al proyecto
los archivos. Seleccionar la opción de compilar.
Los datos de prueba del
programa fueron
|
|
|
1.
2.
3.
h p7.tab.h
#ifndef YYSTYPE
#define YYSTYPE int
#endif
#define NUM 258
#define PABRE 259
#define PCIERRA 260
#define ID 261
#define NL 262
#define IS 263
#define OP_AS 264
#define FINLI 265
#define COMA 266
#define RAYA 267
#define ADMI 268
#define PABREC 269
#define PCIERRAC 270
#define OP_SUM 271
#define OP_MUL 272
extern
YYSTYPE yylval;
h p7.tab.c
/* A Bison parser, made from p7.y
by GNU
Bison version 1.25
*/
#define
YYBISON 1 /* Identify Bison output. */
#define alloca
#define NUM 258
#define PABRE 259
#define PCIERRA 260
#define ID 261
#define NL 262
#define IS 263
#define OP_AS 264
#define FINLI 265
#define COMA 266
#define RAYA 267
#define ADMI 268
#define PABREC 269
#define PCIERRAC 270
#define OP_SUM 271
#define OP_MUL 272
#line 3
"p7.y"
#include
<ctype.h>
#include
<stdio.h>
#include
"p7.tab.h"
#ifndef
YYSTYPE
#define
YYSTYPE int
#endif
#include
<stdio.h>
#ifndef
__cplusplus
#ifndef
__STDC__
#define
const
#endif
#endif
#define YYFINAL 46
#define YYFLAG 32768
#define YYNTBASE 18
#define
YYTRANSLATE(x) ((unsigned)(x) <= 272 ? yytranslate[x] : 31)
static
const char yytranslate[] = { 0,
2,
2, 2, 2,
2, 2, 2,
2, 2, 2,
2,
2, 2, 2,
2, 2, 2,
2, 2, 2,
2,
2, 2, 2,
2, 2, 2,
2, 2, 2,
2,
2, 2, 2,
2, 2, 2,
2, 2, 2,
2,
2, 2, 2,
2, 2, 2,
2, 2, 2,
2,
2, 2, 2,
2, 2, 2,
2, 2, 2,
2,
2, 2, 2,
2, 2, 2,
2, 2, 2,
2,
2, 2, 2,
2, 2, 2,
2, 2, 2,
2,
2, 2, 2,
2, 2, 2,
2, 2, 2,
2,
2, 2, 2,
2, 2, 2,
2, 2, 2,
2,
2, 2, 2,
2, 2, 2,
2, 2, 2,
2,
2, 2, 2,
2, 2, 2,
2, 2, 2,
2,
2, 2, 2,
2, 2, 2,
2, 2, 2,
2,
2, 2, 2,
2, 2, 2,
2, 2, 2,
2,
2, 2, 2,
2, 2, 2,
2, 2, 2,
2,
2, 2, 2,
2, 2, 2,
2, 2, 2,
2,
2, 2, 2,
2, 2, 2,
2, 2, 2,
2,
2, 2, 2,
2, 2, 2,
2, 2, 2,
2,
2, 2, 2,
2, 2, 2,
2, 2, 2,
2,
2, 2, 2,
2, 2, 2,
2, 2, 2,
2,
2, 2, 2,
2, 2, 2,
2, 2, 2,
2,
2, 2, 2,
2, 2, 2,
2, 2, 2,
2,
2, 2, 2,
2, 2, 2,
2, 2, 2,
2,
2, 2, 2,
2, 2, 2,
2, 2, 2,
2,
2, 2, 2,
2, 2, 2,
2, 2, 2,
2,
2, 2, 2,
2, 1, 2,
3, 4, 5,
6,
7, 8, 9,
10, 11, 12,
13, 14, 15,
16,
17
};
#if
YYDEBUG != 0
static
const short yyprhs[] = { 0,
0,
3, 5, 10,
14, 16, 21,
23, 25, 27,
29,
31, 35, 39,
43, 45, 47,
51, 55, 57,
61,
63, 65, 67,
69, 73, 75
};
static
const short yyrhs[] = { 18,
19,
0, 19, 0,
21, 9, 20,
10, 0, 20,
11,
21, 0, 21,
0, 6, 4,
22, 5, 0,
25,
0, 13, 0,
7, 0, 24,
0, 23, 0,
14,
24, 15, 0,
24, 11, 25, 0,
24, 11,
28,
0, 25, 0,
28, 0, 6,
8, 26, 0,
26,
16, 27, 0,
27, 0, 27,
17, 29, 0,
29,
0, 30, 0,
12, 0, 30,
0, 4, 26,
5,
0, 3, 0,
6, 0
};
#endif
#if
YYDEBUG != 0
static
const short yyrline[] = { 0,
32,
33, 36, 39,
40, 43, 44,
45, 46, 49,
50,
53, 56, 57,
58, 59, 62,
65, 66, 69,
70,
73, 74, 77, 78,
81, 82
};
#endif
#if
YYDEBUG != 0 || defined (YYERROR_VERBOSE)
static
const char * const yytname[] = {
"$","error","$undefined.","NUM","PABRE",
"PCIERRA","ID","NL","IS","OP_AS","FINLI","COMA","RAYA","ADMI","PABREC","PCIERRAC",
"OP_SUM","OP_MUL","lista_conj","conj","lista_prop","prop","entre","arreglo",
"param","operacion","expr","termino","expn","factor","term",
NULL
};
#endif
static
const short yyr1[] = { 0,
18,
18, 19, 20,
20, 21, 21,
21, 21, 22,
22,
23, 24, 24,
24, 24, 25,
26, 26, 27,
27,
28, 28, 29,
29, 30, 30
};
static
const short yyr2[] = { 0,
2,
1, 4, 3,
1, 4, 1,
1, 1, 1,
1,
3, 3, 3,
1, 1, 3,
3, 1, 3,
1,
1, 1, 1,
3, 1, 1
};
static
const short yydefact[] = { 0,
0,
9, 8, 0,
2, 0, 7,
0, 0, 1,
0,
26, 27, 23,
0, 0, 11,
10, 15, 16,
22,
0, 27, 17,
19, 21, 24,
0, 5, 0,
6,
0, 0, 0,
0, 3, 0,
12, 13, 14,
25,
18, 20, 4,
0, 0
};
static
const short yydefgoto[] = { 4,
5,
28, 6, 16,
17, 18, 7,
24, 25, 20,
26,
27
};
static
const short yypact[] = { 15,
-2,-32768,-32768, 5,-32768, 7,-32768, 1,
28,-32768,
15,-32768, 16,-32768, 11,
14,-32768, 19,-32768,-32768,
-32768, 28,-32768, 21,
22,-32768,-32768,
25,-32768, 18,
-32768, 11,
4, 28, 28,-32768, 15,-32768,-32768,-32768,
-32768, 22,-32768,-32768, 38,-32768
};
static
const short yypgoto[] = {-32768,
36,-32768,
-11,-32768,-32768, 26, -7,
20, 9, 12,
10,
-5
};
#define YYLAST 45
static
const short yytable[] = { 29,
19,
8, 21, 12,
45, 9, 13,
19, 41, 21,
1,
2, 14, 12,
15, 11, 13,
3, 31, 34,
1,
2, 14, 9,
39, 44, 21,
3, 32, 32,
12,
22, 38, 23,
36, 37, 34,
46, 35, 10,
30,
33, 42, 40,
43
};
static
const short yycheck[] = { 11,
8, 4,
8, 3, 0,
8, 6, 15,
5, 15,
6,
7, 12, 3,
14, 9, 6,
13, 5, 16,
6,
7, 12, 8,
32, 37, 32,
13, 11, 11,
3,
4, 15, 6,
10, 11, 16, 0,
17, 4,
15,
22, 34, 32,
35
};
/*
-*-C-*- /span>Note some compilers choke on
comments on `#line' lines. */
/*
Skeleton output parser for bison,
Copyright (C) 1984, 1989, 1990 Free Software
Foundation, Inc.
This program is free software; you can
redistribute it and/or modify
it under the terms of the GNU General Public
License as published by
the Free Software Foundation; either version
2, or (at your option)
any later version.
This program is distributed in the hope that
it will be useful,
but WITHOUT ANY WARRANTY; without even the
implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU
General Public License
along with this program; if not, write to
the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge,
MA 02139, USA. */
/* As a
special exception, when this file is copied by Bison into a
Bison output file, you may use that output
file without restriction.
This special exception was added by the Free
Software Foundation
in version 1.24 of Bison. */
#ifndef
alloca
#ifdef
__GNUC__
#define
alloca __builtin_alloca
#else /*
not GNU C. */
#if
(!defined (__STDC__) && defined (sparc)) || defined (__sparc__) ||
defined (__sparc) || defined (__sgi)
#include
<alloca.h>
#else /*
not sparc */
#if
defined (MSDOS) && !defined (__TURBOC__)
#include
<malloc.h>
#else /*
not MSDOS, or __TURBOC__ */
#if
defined(_AIX)
#include
<malloc.h>
#pragma alloca
#else /*
not MSDOS, __TURBOC__, or _AIX */
#ifdef
__hpux
#ifdef
__cplusplus
extern
"C" {
void
*alloca (unsigned int);
};
#else /*
not __cplusplus */
void
*alloca ();
#endif /*
not __cplusplus */
#endif /*
__hpux */
#endif /*
not _AIX */
#endif /*
not MSDOS, or __TURBOC__ */
#endif /*
not sparc. */
#endif /*
not GNU C. */
#endif /*
alloca not defined. */
/* This
is the parser code that is written into each bison parser
when the %semantic_parser declaration is not specified
in the grammar.
It was written by Richard Stallman by
simplifying the hairy parser
used when %semantic_parser is specified. */
/* Note:
there must be only one dollar sign in this file.
It is replaced by the list of actions, each
action
as one
case of the switch. */
#define
yyerrok (yyerrstatus = 0)
#define
yyclearin (yychar = YYEMPTY)
#define
YYEMPTY -2
#define
YYEOF 0
#define
YYACCEPT return(0)
#define
YYABORT return(1)
#define
YYERROR goto yyerrlab1
/* Like
YYERROR except do call yyerror.
This remains here temporarily to ease the
transition to the new meaning of YYERROR,
for GCC.
Once GCC version 2 has supplanted version 1,
this can go. */
#define
YYFAIL goto yyerrlab
#define
YYRECOVERING() (!!yyerrstatus)
#define YYBACKUP(token,
value) \
do \
if (yychar == YYEMPTY && yylen == 1) \
{ yychar = (token), yylval = (value); \
yychar1 = YYTRANSLATE (yychar); \
YYPOPSTACK; \
goto yybackup; \
} \
else \
{
yyerror ("syntax error: cannot back up"); YYERROR; } \
while (0)
#define
YYTERROR 1
#define
YYERRCODE 256
#ifndef
YYPURE
#define
YYLEX yylex()
#endif
#ifdef
YYPURE
#ifdef
YYLSP_NEEDED
#ifdef
YYLEX_PARAM
#define
YYLEX yylex(&yylval,
&yylloc, YYLEX_PARAM)
#else
#define
YYLEX yylex(&yylval,
&yylloc)
#endif
#else /*
not YYLSP_NEEDED */
#ifdef
YYLEX_PARAM
#define
YYLEX yylex(&yylval,
YYLEX_PARAM)
#else
#define
YYLEX yylex(&yylval)
#endif
#endif /*
not YYLSP_NEEDED */
#endif
/* If nonreentrant,
generate the variables here */
#ifndef
YYPURE
int yychar; /* the lookahead symbol */
YYSTYPE yylval; /* the semantic value of the */
/* lookahead symbol */
#ifdef
YYLSP_NEEDED
YYLTYPE
yylloc; /* location data for the lookahead */
/* symbol */
#endif
int
yynerrs; /* number of parse errors so far */
#endif /* not YYPURE */
#if
YYDEBUG != 0
int
yydebug; /* nonzero means print parse trace */
/* Since this
is uninitialized, it does not stop multiple parsers
from coexisting. */
#endif
/* YYINITDEPTH indicates the initial size of the
parser's stacks */
#ifndef YYINITDEPTH
#define
YYINITDEPTH 200
#endif
/* YYMAXDEPTH is the maximum size the stacks can
grow to
(effective only if the built-in stack
extension method is used). */
#if
YYMAXDEPTH == 0
#undef
YYMAXDEPTH
#endif
#ifndef
YYMAXDEPTH
#define
YYMAXDEPTH 10000
#endif
/*
Prevent warning if -Wstrict-prototypes.
*/
#ifdef
__GNUC__
int yyparse
(void);
#endif
#if
__GNUC__ > 1 /* GNU C and GNU
C++ define this. */
#define
__yy_memcpy(TO,FROM,COUNT) __builtin_memcpy(TO,FROM,COUNT)
#else /* not GNU C or
C++ */
#ifndef
__cplusplus
/* This
is the most reliable way to avoid incompatibilities
in available built-in functions on various
systems. */
static
void
__yy_memcpy
(to, from, count)
char *to;
char *from;
int count;
{
register char *f = from;
register char *t = to;
register int i = count;
while (i-- > 0)
*t++ = *f++;
}
#else /*
__cplusplus */
/* This
is the most reliable way to avoid incompatibilities
in available built-in functions on various
systems. */
static
void
__yy_memcpy
(char *to, char *from, int count)
{
register char *f = from;
register char *t = to;
register int i = count;
while (i-- > 0)
*t++ = *f++;
}
#endif
#endif
/* The
user can define YYPARSE_PARAM as the name of an argument to be passed
into yyparse. The argument should have type void *.
It should actually point to an object.
Grammar actions can access the variable by
casting it
to the proper pointer type. */
#ifdef
YYPARSE_PARAM
#ifdef
__cplusplus
#define
YYPARSE_PARAM_ARG void *YYPARSE_PARAM
#define
YYPARSE_PARAM_DECL
#else /*
not __cplusplus */
#define
YYPARSE_PARAM_ARG YYPARSE_PARAM
#define
YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
#endif /*
not __cplusplus */
#else /*
not YYPARSE_PARAM */
#define
YYPARSE_PARAM_ARG
#define
YYPARSE_PARAM_DECL
#endif /*
not YYPARSE_PARAM */
int
yyparse(YYPARSE_PARAM_ARG)
YYPARSE_PARAM_DECL
{
register int yystate;
register int yyn;
register short *yyssp;
register YYSTYPE *yyvsp;
int yyerrstatus; /* number of tokens to
shift before error messages enabled */
int yychar1 = 0; /* lookahead
token as an internal (translated) token number */
short yyssa[YYINITDEPTH]; /*
the state stack */
YYSTYPE yyvsa[YYINITDEPTH]; /*
the semantic value stack */
short *yyss = yyssa; /* refer to the
stacks thru separate pointers */
YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to
reallocate them elsewhere */
#ifdef
YYLSP_NEEDED
YYLTYPE yylsa[YYINITDEPTH]; /*
the location stack */
YYLTYPE *yyls = yylsa;
YYLTYPE *yylsp;
#define
YYPOPSTACK (yyvsp--, yyssp--, yylsp--)
#else
#define
YYPOPSTACK (yyvsp--, yyssp--)
#endif
int yystacksize = YYINITDEPTH;
#ifdef
YYPURE
int yychar;
YYSTYPE yylval;
int yynerrs;
#ifdef
YYLSP_NEEDED
YYLTYPE yylloc;
#endif
#endif
YYSTYPE yyval; /* the variable used
to return */
/* semantic values from the action */
/* routines */
int yylen;
#if
YYDEBUG != 0
if (yydebug)
fprintf(stderr, "Starting
parse\n");
#endif
yystate = 0;
yyerrstatus = 0;
yynerrs = 0;
yychar = YYEMPTY; /* Cause a token to be read. */
/* Initialize stack pointers.
Waste one element of value and location
stack
so that they stay on the same level as the
state stack.
The wasted elements are never
initialized. */
yyssp = yyss - 1;
yyvsp = yyvs;
#ifdef
YYLSP_NEEDED
yylsp = yyls;
#endif
/* Push a
new state, which is found in
yystate . */
/* In all
cases, when you get here, the value and location stacks
have just been pushed. so pushing a state
here evens the stacks. */
yynewstate:
*++yyssp = yystate;
if (yyssp >= yyss + yystacksize - 1)
{
/* Give user a chance to reallocate the
stack */
/* Use copies of these so that the
&'s don't force the real ones into memory. */
YYSTYPE *yyvs1 = yyvs;
short *yyss1 = yyss;
#ifdef
YYLSP_NEEDED
YYLTYPE *yyls1 = yyls;
#endif
/* Get the current used size of the three
stacks, in elements. */
int size = yyssp - yyss + 1;
#ifdef
yyoverflow
#ifdef
YYLSP_NEEDED
/* This used to be a conditional around
just the two extra args,
but that might be undefined if yyoverflow is a
macro. */
yyoverflow("parser stack
overflow",
&yyss1, size * sizeof (*yyssp),
&yyvs1, size * sizeof (*yyvsp),
&yyls1, size * sizeof (*yylsp),
&yystacksize);
#else
yyoverflow("parser stack
overflow",
&yyss1, size * sizeof (*yyssp),
&yyvs1, size * sizeof (*yyvsp),
&yystacksize);
#endif
yyss = yyss1; yyvs = yyvs1;
#ifdef
YYLSP_NEEDED
yyls = yyls1;
#endif
#else /*
no yyoverflow */
/* Extend the stack our own way. */
if (yystacksize >= YYMAXDEPTH)
{
yyerror("parser stack overflow");
return 2;
}
yystacksize *= 2;
if (yystacksize > YYMAXDEPTH)
yystacksize = YYMAXDEPTH;
yyss = (short *) alloca (yystacksize *
sizeof (*yyssp));
__yy_memcpy ((char *)yyss, (char *)yyss1,
size * sizeof (*yyssp));
yyvs = (YYSTYPE *) alloca (yystacksize *
sizeof (*yyvsp));
__yy_memcpy ((char *)yyvs, (char *)yyvs1,
size * sizeof (*yyvsp));
#ifdef
YYLSP_NEEDED
yyls = (YYLTYPE *) alloca (yystacksize *
sizeof (*yylsp));
__yy_memcpy ((char *)yyls, (char *)yyls1,
size * sizeof (*yylsp));
#endif
#endif /*
no yyoverflow */
yyssp = yyss + size - 1;
yyvsp = yyvs + size - 1;
#ifdef
YYLSP_NEEDED
yylsp = yyls + size - 1;
#endif
#if
YYDEBUG != 0
if (yydebug)
fprintf(stderr, "Stack size
increased to %d\n", yystacksize);
#endif
if (yyssp >= yyss + yystacksize - 1)
YYABORT;
}
#if
YYDEBUG != 0
if (yydebug)
fprintf(stderr, "Entering state
%d\n", yystate);
#endif
goto yybackup;
yybackup:
/* Do
appropriate processing given the current state.
*/
/* Read a
lookahead token if we need one and don't already have one. */
/*
yyresume: */
/* First try to decide what to do without
reference to lookahead token. */
yyn = yypact[yystate];
if (yyn == YYFLAG)
goto yydefault;
if (yyn < 0)
{
if (yyn == YYFLAG)
goto yyerrlab;
yyn = -yyn;
goto yyreduce;
}
else if (yyn == 0)
goto yyerrlab;
if (yyn == YYFINAL)
YYACCEPT;
/* Shift the lookahead token. */
#if
YYDEBUG != 0
if (yydebug)
fprintf(stderr, "Shifting token %d
(%s), ", yychar, yytname[yychar1]);
#endif
/* Discard the token being shifted unless it
is eof. */
if (yychar != YYEOF)
yychar = YYEMPTY;
*++yyvsp = yylval;
#ifdef
YYLSP_NEEDED
*++yylsp = yylloc;
#endif
/* count tokens shifted since error; after
three, turn off error status. */
if (yyerrstatus) yyerrstatus--;
yystate = yyn;
goto yynewstate;
/* Do the
default action for the current state. */
yydefault:
yyn = yydefact[yystate];
if (yyn == 0)
goto yyerrlab;
/* Do a
reduction. yyn is the number of a rule
to reduce with. */
yyreduce:
yylen = yyr2[yyn];
if (yylen > 0)
yyval = yyvsp[1-yylen]; /* implement
default value of the action */
#if
YYDEBUG != 0
if (yydebug)
{
int i;
fprintf (stderr, "Reducing via rule
%d (line %d), ",
yyn, yyrline[yyn]);
/* Print the symbols being reduced, and their
result. */
for (i = yyprhs[yyn]; yyrhs[i] > 0;
i++)
fprintf (stderr, "%s ",
yytname[yyrhs[i]]);
fprintf (stderr, " -> %s\n",
yytname[yyr1[yyn]]);
}
#endif
switch (yyn) {
}
/* the action file gets copied in in place of
this dollarsign */
yyvsp -= yylen;
yyssp -= yylen;
#ifdef
YYLSP_NEEDED
yylsp -= yylen;
#endif
#if
YYDEBUG != 0
if (yydebug)
{
short *ssp1 = yyss - 1;
fprintf (stderr, "state stack
now");
while (ssp1 != yyssp)
fprintf (stderr, " %d",
*++ssp1);
fprintf (stderr, "\n");
}
#endif
*++yyvsp = yyval;
#ifdef
YYLSP_NEEDED
yylsp++;
if (yylen == 0)
{
yylsp->first_line = yylloc.first_line;
yylsp->first_column =
yylloc.first_column;
yylsp->last_line =
(yylsp-1)->last_line;
yylsp->last_column =
(yylsp-1)->last_column;
yylsp->text = 0;
}
else
{
yylsp->last_line =
(yylsp+yylen-1)->last_line;
yylsp->last_column =
(yylsp+yylen-1)->last_column;
}
#endif
/* Now "shift" the result of the
reduction.
Determine what state that goes to,
based on the state we popped back to
and the rule number reduced by. */
yyn = yyr1[yyn];
yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
if (yystate >= 0 && yystate <=
YYLAST && yycheck[yystate] == *yyssp)
yystate = yytable[yystate];
else
yystate = yydefgoto[yyn - YYNTBASE];
goto yynewstate;
yyerrlab: /* here on detecting error */
if (! yyerrstatus)
/* If not already recovering from an error,
report this error. */
{
++yynerrs;
#ifdef
YYERROR_VERBOSE
yyn = yypact[yystate];
if (yyn > YYFLAG && yyn <
YYLAST)
{
int size = 0;
char *msg;
int x, count;
count = 0;
/* Start X at -yyn if nec to avoid negative indexes in yycheck. */
for (x = (yyn < 0 ? -yyn : 0);
x < (sizeof(yytname) / sizeof(char *)); x++)
if (yycheck[x + yyn] == x)
size += strlen(yytname[x]) + 15, count++;
msg = (char *) malloc(size + 15);
if (msg
!= 0)
{
strcpy(msg, "error en la
hilera");
if (count < 5)
{
count = 0;
for (x = (yyn < 0 ? -yyn : 0);
x < (sizeof(yytname) / sizeof(char
*)); x++)
if (yycheck[x + yyn] == x)
{
strcat(msg, count == 0
? ", expecting `" : " or `");
strcat(msg,
yytname[x]);
strcat(msg,
"'");
count++;
}
}
yyerror(msg);
free(msg);
}
else
yyerror ("error en la hilera; memoria
virtual excedida");
}
else
#endif /*
YYERROR_VERBOSE */
if(yychar != 0)
{yyerror("error
en la hilera");}
else{
printf("\nSe
termino el analisis sin encontrar errores.\n\n");
}
}
goto yyerrlab1;
yyerrlab1: /* here on error raised explicitly by an
action */
if (yyerrstatus == 3)
{
/* if just tried and failed to reuse
lookahead token after an error, discard it.
*/
/* return failure if at end of input */
if (yychar == YYEOF)
YYABORT;
#if
YYDEBUG != 0
if (yydebug)
fprintf(stderr, "Discarding token
%d (%s).\n", yychar, yytname[yychar1]);
#endif
yychar = YYEMPTY;
}
/* Else will try to reuse lookahead token
after shifting the error token. */
yyerrstatus = 3; /* Each real token shifted decrements this */
goto yyerrhandle;
yyerrdefault: /* current state does not do anything special
for the error token. */
#if 0
/* This is wrong; only states that explicitly
want error tokens
should shift them. */
yyn = yydefact[yystate]; /* If its default is to accept any token,
ok. Otherwise pop it.*/
if (yyn) goto yydefault;
#endif
yyerrpop: /* pop the current state because it cannot
handle the error token */
if (yyssp == yyss) YYABORT;
yyvsp--;
yystate = *--yyssp;
#ifdef
YYLSP_NEEDED
yylsp--;
#endif
#if
YYDEBUG != 0
if (yydebug)
{
short *ssp1 = yyss - 1;
fprintf (stderr, "Error: state stack
now");
while (ssp1 != yyssp)
fprintf (stderr, " %d",
*++ssp1);
fprintf (stderr, "\n");
}
#endif
yyerrhandle:
yyn = yypact[yystate];
if (yyn == YYFLAG)
goto yyerrdefault;
yyn += YYTERROR;
if (yyn < 0 || yyn > YYLAST ||
yycheck[yyn] != YYTERROR)
goto yyerrdefault;
yyn = yytable[yyn];
if (yyn < 0)
{
if (yyn == YYFLAG)
goto yyerrpop;
yyn = -yyn;
goto yyreduce;
}
else if (yyn == 0)
goto yyerrpop;
if (yyn == YYFINAL)
YYACCEPT;
#if
YYDEBUG != 0
if (yydebug)
fprintf(stderr, "Shifting error token,
");
#endif
*++yyvsp = yylval;
#ifdef
YYLSP_NEEDED
*++yylsp = yylloc;
#endif
yystate = yyn;
goto yynewstate;
}
#line 84
"p7.y"
yyerror
(s) /* Called by yyparse on error */
char *s;
{
printf ("%s\n", s);
}
main ()
{
printf("_______________________________________________________________________\n");
printf("Digite
el programa a analizar, para terminar escriba \"eof\"\n");
printf("_______________________________________________________________________\n\n");
yyparse
();
}