LINUX.ORG.RU

История изменений

Исправление 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();
}

С тебя большой пирожок. ;)