История изменений
Исправление beastie, (текущая версия) :
Переводит из простой нотации в RPN (за правильнось поведения со скобками не ручаюсь — это тебе на домашнее задание, но `dc' говорит, что верно):
%{
#include <ctype.h>
#include <stdio.h>
%}
%union {
int i;
char s[1024];
}
%token <i> NUMBER
%type <s> expr
%left '+' '-'
%left '*' '/'
%left NEG
%%
stmt
: /* empty */
| stmt expr '\n' { puts($2); }
| stmt error '\n' { yyerrok; }
;
expr
: NUMBER { snprintf($$, sizeof($$), "%d", $1); }
| expr '+' expr { snprintf($$, sizeof($$), "%s %s +", $3, $1); }
| expr '-' expr { snprintf($$, sizeof($$), "%s %s -", $3, $1); }
| expr '*' expr { snprintf($$, sizeof($$), "%s %s *", $3, $1); }
| expr '/' expr { snprintf($$, sizeof($$), "%s %s /", $3, $1); }
| '-' expr %prec NEG { snprintf($$, sizeof($$), "-%s", $2); }
| '(' expr ')' { snprintf($$, sizeof($$), "%s", $2); }
;
%%
int
yyerror(char *s)
{
fprintf(stderr, "Error: %s\n", s);
}
int
yylex()
{
int c;
while ((c = getchar()) == ' ' || c == '\t')
;
if (c == EOF)
return 0;
if (isdigit(c)) {
ungetc(c, stdin);
scanf("%li", &yylval.i);
return NUMBER;
}
return c;
}
int
main ()
{
yyparse();
}
С тебя большой пирожок. ;)
Исправление beastie, :
Переводит из простой нотации в RPN (за правильнось поведения со скобками не ручаюсь — это тебе на домашнее задание, но `dc' говорит, что верно):
%{
#include <ctype.h>
#include <stdio.h>
%}
%union {
int i;
char s[1024];
}
%token <i> NUMBER
%type <s> expr
%left '+' '-'
%left '*' '/'
%left NEG
%%
stmt
: /* empty */
| stmt expr '\n' { puts($2); }
| stmt error '\n' { yyerrok; }
;
expr
: NUMBER { snprintf($$, sizeof($$), "%d", $1); }
| expr '+' expr { snprintf($$, sizeof($$), "%s %s +", $3, $1); }
| expr '-' expr { snprintf($$, sizeof($$), "%s %s -", $3, $1); }
| expr '*' expr { snprintf($$, sizeof($$), "%s %s *", $3, $1); }
| expr '/' expr { snprintf($$, sizeof($$), "%s %s /", $3, $1); }
| '-' expr %prec NEG { snprintf($$, sizeof($$), "-%d", $2); }
| '(' expr ')' { snprintf($$, sizeof($$), "%s", $2); }
;
%%
int
yyerror(char *s)
{
fprintf(stderr, "Error: %s\n", s);
}
int
yylex()
{
int c;
while ((c = getchar()) == ' ' || c == '\t')
;
if (c == EOF)
return 0;
if (isdigit(c)) {
ungetc(c, stdin);
scanf("%li", &yylval.i);
return NUMBER;
}
return c;
}
int
main ()
{
yyparse();
}
С тебя большой пирожок. ;)
Исходная версия beastie, :
Переводит из простой в RPN нотацию (за правильнось поведения со скобками не ручаюсь — это тебе на домашнее задание, но `dc' говорит, что верно):
%{
#include <ctype.h>
#include <stdio.h>
%}
%union {
int i;
char s[1024];
}
%token <i> NUMBER
%type <s> expr
%left '+' '-'
%left '*' '/'
%left NEG
%%
stmt
: /* empty */
| stmt expr '\n' { puts($2); }
| stmt error '\n' { yyerrok; }
;
expr
: NUMBER { snprintf($$, sizeof($$), "%d", $1); }
| expr '+' expr { snprintf($$, sizeof($$), "%s %s +", $3, $1); }
| expr '-' expr { snprintf($$, sizeof($$), "%s %s -", $3, $1); }
| expr '*' expr { snprintf($$, sizeof($$), "%s %s *", $3, $1); }
| expr '/' expr { snprintf($$, sizeof($$), "%s %s /", $3, $1); }
| '-' expr %prec NEG { snprintf($$, sizeof($$), "-%d", $2); }
| '(' expr ')' { snprintf($$, sizeof($$), "%s", $2); }
;
%%
int
yyerror(char *s)
{
fprintf(stderr, "Error: %s\n", s);
}
int
yylex()
{
int c;
while ((c = getchar()) == ' ' || c == '\t')
;
if (c == EOF)
return 0;
if (isdigit(c)) {
ungetc(c, stdin);
scanf("%li", &yylval.i);
return NUMBER;
}
return c;
}
int
main ()
{
yyparse();
}
С тебя большой пирожок. ;)