2015-04-16 2 views
0

Je suis nouveau dans les programmes lex et yacc. J'ai essayé d'écrire un programme yacc qui prend en entrée une expression arithmétique et donne une notation postfixée en sortie. La grammaire que j'utilise est: exp: exp + term | exp - terme | terme terme: terme * facteur | terme/facteur | facteur facteur: numProgramme yacc pour convertir l'expression arithmétique en postfix

Ceci est mon code lex:

%{ 
extern int yylval; 
#include "y.tab.h" 
%} 

%% 

[0-9]+ {yylval = atoi(yytext);return INTEGER;} 
[ \t\n]  /* skip whitespace */ 
. {return *yytext;} 
%% 

int yywrap(void) { 
return 1; 
} 

Voici mon programme yacc:

%{ 
#include<stdio.h> 
%} 
%token INTEGER 
%left '+' '-' 
%left '*' '/' 
%% 

E: E '+' T {printf("+");} 
    | E '-' T {printf("-");} 
    | T  
    ; 

T: T '*' F {printf("*");} 
    | T '/' F {printf("/");} 
    | F 
    ;  

F: '(' E ')' 
    | INTEGER {printf("%d",yylval);} 
    ; 

%% 

int main(){ 
    yyparse(); 
} 

int yyerror (char *msg) { 
    return printf ("error YACC: %s\n", msg); 
} 

Mais ce code est la compilation sortie correctly.But n'est pas correcte si « + 'ou' - 'sont utilisés dans l'expression Par exemple entrée: 2 + 3 sortie: 23 (au lieu de 23+) S'il vous plaît aidez-moi à trouver l'erreur dans le code. Merci.

+0

Votre grammaire n'accepte qu'une seule expression. Si vous fermez l'entrée après l'expression, elle s'imprimera correctement. – rici

+0

Notez également que vous n'avez pas besoin du T non-terminal car vous spécifiez la même chose en utilisant la priorité de l'opérateur. – user3344003

Répondre

2

Si vous entrez 2 + 3, et rien de plus, l'analyseur ne sait pas que vous vouliez que ce soit une expression complète. Ce pourrait être le début de l'expression 2 + 3 * 4. Donc, l'analyseur se trouve là et attend plus de commentaires. Essayez d'ajouter un jeton de fin d'expression, tel qu'un point-virgule, à votre grammaire.

-1

Les notations infix et postfix sont les résultats de la marche d'un AST dans différents ordres. Donc, vous devez commencer par construire l'AST pour avoir quelque chose à marcher dans l'ordre choisi après l'AST est terminée.

Dans les actions sémantiques, vous devez créer des nœuds qui pointent vers les nœuds dont ils sont constitués. Ensuite, marchez dans l'arbre après l'achèvement:

%start start 

%% 

start: E { walk_post_order($1); } 
+2

Ce n'est vraiment pas vrai. Les actions que l'OP a posté sont suffisantes pour marcher dans l'arbre d'analyse. Il n'est pas toujours nécessaire de construire un AST: les compilateurs de production ont été construits sans un. – EJP

0

\ n {return (0); }

ajoutez simplement cette ligne dans la section des règles de votre code dans votre fichier lex :)

+3

Pourquoi est-ce? Une petite explication serait utile. – showdev