Related articles |
---|
if-then-else under yacc davegb@nospam.pobox.com (Dave Brotherstone) (2001-07-23) |
Re: if-then-else under yacc davegb@pobox.com (Dave Brotherstone) (2001-07-27) |
Re: if-then-else under yacc kvinay@ip.eth.net (Vinay Kakade) (2001-07-27) |
From: | Vinay Kakade <kvinay@ip.eth.net> |
Newsgroups: | comp.compilers |
Date: | 27 Jul 2001 02:52:01 -0400 |
Organization: | Compilers Central |
References: | 01-07-120 |
Keywords: | yacc, parse |
Posted-Date: | 27 Jul 2001 02:52:01 EDT |
Hi,
Dave Brotherstone wrote:
> the no-ops come out first, because it has to evaluate "stmt" within the rule
> for IF before it evaluates the rule for IF. (Ignoring labels for now, as
> this can be done later, it is just the problem with the ordering that is the
> main concern).
I have solved this problem by using semantic actions "within" a grammar rule.
You can find complete source code, along with sample input and output at
the end of this mail.
If you do not want to write semantic actions within grammar rules, a simple
madification of the code can be done so that it incorporates marker
non-terminals.
Hope you find this useful.
-Vinay Kakade.
---------------------------------------------------------------------------------
%{
/* ---------------------------------------------------------------------------
* test.l: Lex source code for the parser test.y
* --------------------------------------------------------------------------
*/
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include "y.tab.h"
%}
delim [ \n\t]
num [0-9]+
comment #.*
%%
{delim} ;
{comment} ;
"if" return IF;
{num} { yylval.val = atoi(yytext); return NUM; }
"<" { yylval.str = strdup(yytext); return TEST; }
"noop" return NOOP;
"endif" return ENDIF;
";" return ';';
. printf("Unrecognized symbol in input file: %s\n", yytext);
%%
int yyerror(char *str)
{
printf("%s\n", str);
return EXIT_FAILURE;
}
/* end test.l */
%{
/* --------------------------------------------------------------------------
* test.y: Yacc specification file for "if" statement
* --------------------------------------------------------------------------
*/
# include <stdio.h>
%}
%union
{
int val;
char *str;
}
%token IF ENDIF NOOP
%token <str> TEST
%token <val> NUM
%type <val> expr
%%
stmt_list : /* empty */
| stmt ';' stmt_list
;
stmt : IF { printf("[if] "); } expr TEST expr
{ printf("[%s] [%d] [%d] ", $4, $3, $5); }
stmt_list ENDIF
| noop
;
noop : NOOP { printf("[NOOP] "); }
;
expr : NUM
;
%%
int main()
{
yyparse();
}
/* end test.y */
# A sample input file
if 17 < 45
noop ;
noop ;
endif ;
# sample output
[vinay@vinaycomp compilers]./test < ip
[if] [<] [17] [45] [NOOP] [NOOP]
----------------------------------------------------------------------------
Return to the
comp.compilers page.
Search the
comp.compilers archives again.