ioProgrammo Community

Linguaggi di programmazione => Tutti gli altri linguaggi => Discussione aperta da: Kanuc - Settembre 01, 2017, 11:48:08



Titolo: Flex e Bison
Inserito da: Kanuc - Settembre 01, 2017, 11:48:08
Salve, qualcuno di voi conosce questi due linguaggi? Ho bisogno di aiuto al riguardo per un progetto perchè non riesco a trovare un errore.
HELP!!!  :'(

Il mio progetto è questo: Si costruisca, utilizzando la coppia di programmi FLEX e BISON, un programma in grado diriconoscere un linguaggio che permette di calcolare delle espressioni booleane.Il file in input (specificato come parametro nella riga di comando) è
composto da un’intestazione seguita da una lista di operazioni eseguite su variabili booleane.
Un esempio di intestazione è il seguente:
Data: 30/maggio/2016;

Nell’intestazione è contenuta una data.


Il mio codice in FLEX è questo:
Codice:
%{
#include "boolean.tab.h"
#include <string.h>
%}

%option noyywrap

%%

[0-9]+"/"[0-9]+"/"[0-9]+     return DATANUMERICA;
Data return DATA;
VAR return VAR;
AND                  return AND;
OR                  return OR;
NOT                  return NOT;
FALSE                return FALSE;
TRUE                return TRUE;
[_a-zA-Z0-9]+    { yylval.string = strdup(yytext); return ID;}
[():;,/]              return *yytext;
[ \n\t\r]            ;

%%

Il codice scritto in BISON:
Codice:
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define HASHSIZE 101

/*Definizione della Struttura della Symbol Table*/
struct nlist {
struct nlist *next;
char *name;
int value;
};

struct nlist *hashtab[HASHSIZE];

unsigned int hash(char *s);

struct nlist *lookup(char *s);
struct nlist *ins_attr(char *s,int i);
struct nlist *ins_token(char *name) ;

void yyerror (char const *);
int curr_attr;
%}


%token DATANUMERICA DATA FALSE TRUE VAR AND OR NOT '(' ')' ',' ';' ':'
%token <string> ID
%type <boolean> truth_value
%type <boolean> expr


%union {
  int boolean;
  char *string;
}

%left OR
%left AND
%right NOT

%start program

%%

program: date_declaration list_expr;

date_declaration:
      DATA ':' DATANUMERICA ';'
      ;

list_expr:
      /* empty expression */
      |
      expr maybe_vars ';' list_expr
           
      ;

maybe_vars:
      /* empty list of vars */
      |
      ':' nonempty_list_vars
      ;

nonempty_list_vars:
     VAR ID {
              ins_token($2);
              ins_attr($2, curr_attr);
              if (curr_attr)
                printf("%s=TRUE;",$2);
              else
                printf("%s=FALSE;",$2);
            }
      |
     VAR ID ',' nonempty_list_vars {
            ins_token($2);
            ins_attr($2, curr_attr);
            if (curr_attr)
              printf("%s=TRUE;",$2);
            else
              printf("%s=FALSE;",$2);
            }
      ;

truth_value:
      TRUE { $$ = 1; }
      |
      FALSE { $$ = 0; }
      ;

expr:
      ID { $$=0; curr_attr = $$; }
      |
      truth_value { $$=$1; curr_attr = $$; }
      |
      '(' expr ')' { $$=$2; curr_attr = $$; }
      |
      expr OR expr { $$=($1 || $3); curr_attr = $$; }
      |
      expr AND expr { $$=($1 && $3); curr_attr = $$; }
      |
      NOT expr { $$=!$2; curr_attr = $$; }
      ;
 
%%

void yyerror (char const *s) {
fprintf(stderr, "%s\n", s);
}

int main() {
yyparse();
return 0;
}

unsigned int hash(char *s) {
/* calcolare HASH di s;*/
int h=0;
for(;*s!='\0';s++)
   h=(127*h+*s)%HASHSIZE;
   /*printf("%i : hash\r\n",h);*/
return h;
             
}

struct nlist *lookup(char *s) {
/* cercare s nella tabella HASH */
struct nlist *np;
for (np = hashtab[hash(s)]; np != NULL;np = np->next)
               if (strcmp(s,np->name) == 0)
return np;
return NULL;
}

struct nlist *ins_attr(char *s,int i) {
/* cercare s nella tabella HASH e inserisce l'attributo i*/
struct nlist *np;
np=lookup(s);
if(np!=NULL){
np->value=i;
return np;
        }
return NULL;
}

struct nlist *ins_token(char *name) {
/* inserire  l'elemento di token */
struct nlist *np;
unsigned hashval;
if ((np = lookup(name)) == NULL) {                                /*se non è già presente*/
if ((np = (struct nlist *)malloc(sizeof(*np)))==NULL)
   return NULL;
np->name = strdup(name);
np->value=0;
hashval = hash(name);
np->next = hashtab[hashval];
hashtab[hashval] = np;
}
return np;

}

Esempio di input:

Data: 30/aprile/2016;
FALSE : VAR a1, VAR B, VAR c;
TRUE : VAR d_2;
NOT a1 AND B;
NOT ( (a1 AND c) OR (B AND d_2) ) : VAR F, VAR h ;
FALSE : VAR m;
TRUE :VAR l, VAR i;
F OR FALSE OR m OR TRUE OR TRUE : VAR R ;

Esempio di output:
a1=FALSE; B=FALSE; c=FALSE;
d_2=TRUE;
FALSE;
F=TRUE; h=TRUE;
m=FALSE;
l=TRUE; i=TRUE;
R=TRUE;

E invece ottengo:
Codice:
c=FALSE; B=FALSE; a1=FALSE; d_2=TRUE; h=TRUE; F=TRUE;m=FALSE;i=TRUE; l=TRUE;R=TRUE;
cioè l'ordine è al contrario come se partisse alla fine e tornare in testa.

Ho provato a modificare l'ultima parte del file di Bison , nella parte in C, così:
Codice:
struct nlist *ins_token(char *name) {
/* inserire  l'elemento di token */
struct nlist *np, *p_1;
unsigned hashval;
if ((np = lookup(name)) == NULL) {                              /*se non è già presente*/
if ((np = (struct nlist *)malloc(sizeof(*np)))==NULL)
   return NULL;
np->name = strdup(name);
np->value=0;
np->next= NULL;
hashval = hash(name);
p_1= hashtab[hashval];
while (p_1 != NULL && p_1->next != NULL)
  p_1 = p_1->next;
if(p_1 == NULL)
  hashtab[hashval] = np;
else 
  p_1->next = np;   
}
return hashtab[hashval];
}

ma niente, mi stampa i primi due (al contrario) e poi va in crash!
Non capisco dove sia l'errore!
HELP!!!


powered by Simple Machines 1
powered by Simple Machines