Foros del Web » Programación para mayores de 30 ;) » Programación General »

Ayuda con Lex y Yacc

Estas en el tema de Ayuda con Lex y Yacc en el foro de Programación General en Foros del Web. La cosa es que tengo el código de Lex: %{ /************************************************** ************************** lexer.l Lexical analyser for a simple calculator. The lexical analyser is implemented using ...
  #1 (permalink)  
Antiguo 18/02/2006, 17:38
 
Fecha de Ingreso: febrero-2006
Mensajes: 4
Antigüedad: 18 años, 2 meses
Puntos: 0
Ayuda con Lex y Yacc

La cosa es que tengo el código de Lex:

%{
/************************************************** **************************
lexer.l
Lexical analyser for a simple calculator. The lexical analyser is
implemented using a C++ class. This is specified by selecting the -Tcpp
option in ALex (the "C++" selection from the Target Language combo box in
the ALex Options dialog box).
************************************************** **************************/

#include <stdlib.h>
#include <math.h>
#include <assert.h>
#include "parser.h"
%}

// include file
%include {
// forward references
class calc_parser;
class symboltable;
}

// lexical analyser name
%name calc_lexer

// class definition
{
// Attributes
protected:
symboltable* m_symboltable; // the symbol table

// Operations
public:
int create(calc_parser* parser, symboltable* symboltable);

// attribute commands
double number() const;
symbol* id() const;
}

// constructor
{
// do nothing
}

// macros
exponent ([Ee][+-]?[0-9]+)

%%

%{
// extract yylval for use later on in actions
YYSTYPE& yylval = *(YYSTYPE*)yyparserptr->yylvalptr;
%}

// number
[0-9]+"."[0-9]*{exponent}? |
"."[0-9]+{exponent}? |
[0-9]+{exponent}? { yylval.value = number(); return NUMBER; }

// keywords
"sin" { return SIN; }
"cos" { return COS; }
"tan" { return TAN; }

// id
[a-zA-Z_][a-zA-Z0-9_]* { yylval.symbol = id(); return ID; }

// operators
"=" { return '='; }
"+" { return '+'; }
"-" { return '-'; }
"*" { return '*'; }
"/" { return '/'; }
"(" { return '('; }
")" { return ')'; }

// white space
[ \t] { /* do nothing */ }
\n { return '\n'; }

. { printf("invalid character '0x%02x'\n", (unsigned int)yytext[0]); }

%%

/////////////////////////////////////////////////////////////////////////////
// calc_lexer commands

int calc_lexer::create(calc_parser* parser, symboltable* symboltable)
{
assert(parser != NULL);
assert(symboltable != NULL);

m_symboltable = symboltable;
return yycreate(parser);
}

/////////////////////////////////////////////////////////////////////////////
// calc_lexer attribute commands

double calc_lexer::number() const
{
errno = 0; // clear error flag
char* endp;
double d = strtod(yytext, &endp);
if ((d == +HUGE_VAL || d == -HUGE_VAL) && errno == ERANGE) {
printf("number too big\n");
}
return d;
}

symbol* calc_lexer::id() const
{
symbol* p = m_symboltable->install(yytext);
return p;
}


Y el de Yacc:

%{
/************************************************** **************************
parser.y
Parser for a simple calculator. The parser is implemented using a C++ class.
This is specified by selecting the -Tcpp option in AYACC (the "C++"
selection from the Target Language combo box in the AYACC Options dialog
box).

The parser implements the usual floating point arithmetic using the
addition, subtraction, multiplication and division operators, and unary
minus. Expressions can be grouped and simple error recovery is supported. In
addition it is now posssible to assign values to variables, and to use such
values in expressions.
************************************************** **************************/

#include <math.h>
%}

// include file
%include {
// forward references
class symbol;
}

// attribute type
%union {
symbol* symbol;
double value;
}

// nonterminals
%type <value> expr

// tokens
%right '='
%left '+', '-'
%left '*', '/'
%right UMINUS

%token <value> NUMBER
%token <symbol> ID

// keywords
%token SIN
%token COS
%token TAN

// include file
%include {
#include "symbol.h"
#include "lexer.h"
}

// parser name
%name calc_parser

// class definition
{
// Attributes
protected:
symboltable m_symboltable; // the symbol table
calc_lexer m_lexer; // the lexical analyser

// Operations
public:
int create();

// attribute commands
double assign(symbol* id, double value);
double divide(double dividend, double divisor);
}

// constructor
{
// do nothing
}

%%
lines
: lines line
| /* empty */
;

line
: expr '\n' { printf("%g\n", (double)$1); }
| error '\n' { yyerrok(); }
;

expr
: ID '=' expr { $$ = assign($1, $3); }
| expr '+' expr { $$ = $1 + $3; }
| expr '-' expr { $$ = $1 - $3; }
| expr '*' expr { $$ = $1 * $3; }
| expr '/' expr { $$ = divide($1, $3); }
| '(' expr ')' { $$ = $2; }
| '-' expr %prec UMINUS { $$ = -$2; }
| NUMBER { $$ = $1; }
| ID { $$ = $1->m_value; }
| SIN '(' expr ')' { $$ = sin($3); }
| COS '(' expr ')' { $$ = cos($3); }
| TAN '(' expr ')' { $$ = tan($3); }
;

%%

/////////////////////////////////////////////////////////////////////////////
// main

int main(void)
{
int n = YYEXIT_FAILURE;

calc_parser parser;
if (parser.create()) {
n = parser.yyparse();
}
return n;
}

/////////////////////////////////////////////////////////////////////////////
// calc_parser commands

int calc_parser::create()
{
if (!yycreate(&m_lexer)) {
return 0;
}
if (!m_lexer.create(this, &m_symboltable)) {
return 0;
}
return 1; // success
}

/////////////////////////////////////////////////////////////////////////////
// calc_parser attribute commands

double calc_parser::assign(symbol* id, double value)
{
assert(id != NULL);

id->m_value = value;
return id->m_value;
}

double calc_parser::divide(double a, double b)
{
if (b == 0) {
printf("division by zero\n");
yythrowerror(); // causes a syntax error
return 0;
}
else {
return a / b;
}
}


Pero el problema es que no se como meterle el archivo de entrada y empezar a analizarlo. Por favor, cualquier ayuda se los agradecería mucho.
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 12:38.