У меня есть программа-улитка, которая должна интерпретироваться моим кодом Yacc. Однако у меня возникли проблемы с синтаксическим анализом оператора IF-ELSE в исходном коде улитки из файла .y
Это моя программа Snail
print "Start of Program";
print newline;
print 4+5*2;
print newline;
//testing 3 < 4
if (3 < 4) then
print "3 is smaller than 4";
print newline;
else
print "your interpreter is not working";
endif
Это моя (.l) flex code (Lexical Analyzer)
%{
#include "y.tab.h"
#include <string.h>
#include <stdlib.h>
int linenum=1;
int temp_int;
char temp_str[200];
%}
%%
\n {linenum++;}
[\t ] /* skip spaces */;
\/\/[^\n]* /* ignore comments */;
"+" {return '+';}
"-" {return '-';}
"*" {return '*';}
"/" {return '/';}
")" {return ')';}
"(" {return '(';}
"<" {return '<';}
">" {return '>';}
";" {return ';';}
"print" {return PRINT;}
"newline" {return NEWLINE;}
"if" {return IF;}
"then" {return THEN;}
"else" {return ELSE;}
"endif" {return ENDIF;}
[0-9]+ {sscanf(yytext, "%d", &temp_int);
yylval.int_val = temp_int;
return INT;}
\"[^"\n]*\" {strncpy(temp_str, &(yytext[1]), strlen(yytext)-2);
temp_str[strlen(yytext)-2] = (char) 0;
yylval.str_val = temp_str;
return STRING;}
. {printf("LEX: unknown input string found in line %d \n", linenum); abort();}
%%
int yywrap() {return 1;}
Это мой (.y) код yacc
/* Put new code here */
%{
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int yyerror(char *s);
extern int linenum;
%}
/* define all types of variables and terminals */
%union
{
int int_val;
char *str_val;
}
/* define the individual types of variables and terminals */
%token PRINT
%token NEWLINE
%token IF
%token THEN
%token ELSE
%token ENDIF
%token <str_val> STRING
%token <int_val> INT
%type <int_val> expr
/* assign priorities to operators in order to avoid shift/reduce conflicts (grammar ambiguities) */
%left '+' '-'
%left '*' '/'
%left '<' '>'
%left UMINUS
/* the start variable of your program */
%start program
%%
program : stmt_list
| error {printf("YACC: syntax error near line %d \n", linenum);
abort();}
;
stmt_list : stmt_list stmt
| stmt
;
stmt : print_stmt
| if_stmt
print_stmt : expr ';' {printf("expression found\n");}
| PRINT expr ';' {if (top() == 1) then {printf("%d", $2);}}
| PRINT STRING ';' {printf("%s", $2);}
| PRINT NEWLINE ';' {printf("\n");}
if_stmt : IF expr THEN {top()==1 ? push($2!=0) : push(0);} stmt_list {pop();}
| ELSE {top()==1 ? push($2==0) : push(0);} stmt_list {pop();} ENDIF
expr : '(' expr ')' {$$ = $2;}
| expr '+' expr {$$ = $1 + $3;}
| expr '-' expr {$$ = $1 - $3;}
| expr '*' expr {$$ = $1 * $3;}
| expr '/' expr {$$ = $1 / $3;}
| expr '<' expr {$$ = $1 < $3;}
| expr '>' expr {$$ = $1 > $3;}
| expr '<=' expr {$$ = $1 >= $3;}
| expr '>=' expr {$$ = $1 <= $3;}
| expr '==' expr {$$ = $1 == $3;}
| expr '!=' expr {$$ = $1 != $3;}
| '-' expr %prec UMINUS {$$ = -$2;}
| INT {$$ = $1;}
;
%%
/* link lex code */
/* #include "lex.yy.c" */
/* insert additional code here */
int main(void)
{
return yyparse();
}
int yyerror(char *s)
{
fprintf(stderr, "%s \n",s);
}
Это мой фактический вывод
Start of Program
14
3 is smaller than 4
your interpreter is not working
Этомой ожидаемый результат
Start of Program
14
3 is smaller than 4
Может кто-нибудь помочь с некоторыми советами о том, как правильно проанализировать оператор IF-ELSE? Спасибо!