2009-11-17 12 views
0

J'ai créé un programme censé reconnaître une grammaire simple. Quand j'introduis ce que je pense être supposé être une déclaration valide, j'obtiens une erreur. Spécifiquement, si je tapePourquoi ai-je une erreur de syntaxe dans mon programme fait avec flex et yacc?

int a;

int b;

cela ne fonctionne pas. Après avoir tapé int a; le programme fait écho; pour certaines raisons. Puis quand je tape int b; J'ai une erreur de syntaxe.

Le fichier lex:

%{ 
#include <stdlib.h> 
#include <ctype.h> 
#include <string.h> 

#include "y.tab.h" 

%} 

else ELSE 
if IF 
int INT|int 
return RETURN 
void VOID 
while WHILE 
id [a-zA-Z]* 
num [0-9]* 
lte <= 
gte >= 
equal == 
notequal != 

%% 

{else} { return ELSE; } 
{if} { return IF; } 
{int} { return INT; } 
{return} { return RETURN; } 
{void} { return VOID; } 
{while} { return WHILE; } 
{id} {  return ID; } 
{num} {  return NUM; } 
{lte} {  return LTE; } 
{gte} {  return GTE; } 
{equal} { return EQUAL; } 
{notequal} { return NOTEQUAL; } 
%% 

Le fichier yacc:

/* C-Minus BNF Grammar */ 

%token ELSE 
%token IF 
%token INT 
%token RETURN 
%token VOID 
%token WHILE 

%token ID 
%token NUM 

%token LTE 
%token GTE 
%token EQUAL 
%token NOTEQUAL 
%% 

program : declaration_list ; 

declaration_list : declaration_list declaration | declaration ; 

declaration : var_declaration | fun_declaration ; 

var_declaration : type_specifier ID ';' 
       | type_specifier ID '[' NUM ']' ';' ; 

type_specifier : INT | VOID ; 

fun_declaration : type_specifier ID '(' params ')' compound_stmt ; 

params : param_list | VOID ; 

param_list : param_list ',' param 
      | param ; 

param : type_specifier ID | type_specifier ID '[' ']' ; 

compound_stmt : '{' local_declarations statement_list '}' ; 

local_declarations : local_declarations var_declaration 
        | /* empty */ ; 

statement_list : statement_list statement 
       | /* empty */ ; 

statement : expression_stmt 
      | compound_stmt 
      | selection_stmt 
      | iteration_stmt 
      | return_stmt ; 

expression_stmt : expression ';' 
       | ';' ; 

selection_stmt : IF '(' expression ')' statement 
       | IF '(' expression ')' statement ELSE statement ; 

iteration_stmt : WHILE '(' expression ')' statement ; 

return_stmt : RETURN ';' | RETURN expression ';' ; 

expression : var '=' expression | simple_expression ; 

var : ID | ID '[' expression ']' ; 

simple_expression : additive_expression relop additive_expression 
        | additive_expression ; 

relop : LTE | '<' | '>' | GTE | EQUAL | NOTEQUAL ; 

additive_expression : additive_expression addop term | term ; 

addop : '+' | '-' ; 

term : term mulop factor | factor ; 

mulop : '*' | '/' ; 

factor : '(' expression ')' | var | call | NUM ; 

call : ID '(' args ')' ; 

args : arg_list | /* empty */ ; 

arg_list : arg_list ',' expression | expression ; 

Répondre

1

Ok ... vous devez ajouter un point-virgule comme un gage aussi bien dans votre langue spec ... en tant que fyi, faites une recherche sur google ... il y a aussi quelques fichiers lex/yacc pour le langage de programmation en C ... et il y a beaucoup de tutoriels sur ce sujet ... flex/bison ne pardonne pas vraiment au programme erreurs de spécification ... vous avez vraiment besoin de comprendre les éléments de son fonctionnement ... Recherchez le fameux tutoriel de Jack Crenshaw sur la façon de construire un compilateur.

+0

Si j'ai ajouté un point-virgule, qu'aurais-je revenir? Dois-je changer toutes les instances de ';' dans le fichier yacc, ou puis-je les laisser comme ça? – neuromancer

1

Lex:

id [a-zA-Z]* 
num [0-9]* 

les deux cas peuvent rencontrer des chaînes vides, utiliser '+' au lieu

+0

Ne résout pas le problème, mais c'est vrai. – neuromancer

+0

@Phenom - ajouter la ligne suivante à la lex: "newline \ n" Par défaut, le traitement de l'espace ne peut pas reconnaître la combinaison \ r \ n – Dewfy