Witam,
Ponizej kalkulator liczb rzymskich , ktory ma wczytywac liczby rzymskie np. XI + VIII nastepnie przerabiac na arabskie w celu zrobienia obliczen po czym wyswietlac w wyniku rezultat jako liczbe rzymska czyli w tym przypadku XIX
Udalo mi sie dojsc do czegos takiego tylko ze niestety po uruchomieniu i wpisaniu dzialania pojawia sie blad naruszenia ochrony pamieci. Prosze o pomoc.
plik bisona :
%{
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define YYSTYPE char
//extern int yylex();
char zmienNaRzymska(int liczba);
%}
%token NUMBER
%token PLUS MINUS TIMES DIVIDE POWER
%token LEFT RIGHT
%token END
%token rzymska
%left PLUS MINUS
%left TIMES DIVIDE
%left NEG
%right POWER
%start Input
%%
Input:
| Input Line
;
Line:
END
| Expression END { printf("Result: %s\n", $1); }
;
Expression:
NUMBER { $$=$1; }
| Expression PLUS Expression { $$=zmienNaRzymska(zmienNaArabska($1)+zmienNaArabska($3)); }
| Expression MINUS Expression { $$=zmienNaRzymska(zmienNaArabska($1)-zmienNaArabska($3)); }
| Expression TIMES Expression { $$=zmienNaRzymska(zmienNaArabska($1)*zmienNaArabska($3)); }
| Expression DIVIDE Expression { $$=zmienNaRzymska(zmienNaArabska($1)/zmienNaArabska($3)); }
| MINUS Expression %prec NEG { $$=-$2; }
| Expression POWER Expression { $$=zmienNaRzymska(pow(zmienNaArabska($1),zmienNaArabska($3))); }
| LEFT Expression RIGHT { $$=$2; }
;
%%
int yyerror(char *s) {
printf("%s\n", s);
}
char zmienNaRzymska(int liczba) {
int arab[13]={1000, 900 , 500 , 400 , 100 , 90 ,50 ,40 , 10 ,9 ,5,4,1};
int ilosc,i,j;
static char wynik[20];
for (i=0;i<=12;i++)
{
ilosc=liczba/arab[i];
liczba%=arab[i];
for (j=1;j<=ilosc;j++)
{
switch (i){
case 0: {strcat(wynik,"M") ;break;}//1000
case 1: {strcat(wynik,"CM");break;}//900
case 2: {strcat(wynik,"D");break;}//500
case 3: {strcat(wynik,"CD");break;}//400
case 4: {strcat(wynik,"C");break;}//100
case 5: {strcat(wynik,"XC");break;}//90
case 6: {strcat(wynik,"L");break;}//50
case 7: {strcat(wynik,"XL");break;}//40
case 8: {strcat(wynik,"X") ;break;}//10
case 9: {strcat(wynik,"IX");break;}//9
case 10: {strcat(wynik,"V") ;break;}//5
case 11: {strcat(wynik,"IV");break;}//4
case 12: {strcat(wynik,"I");break;}//1
}
}
}
return *wynik;
}
int zmienNaArabska(char* rzym) {
int arabska =0,i;
for (i=0;i<strlen(rzym);i++)
{
if (rzym[i]=='D') arabska+=500;else
if (rzym[i]=='L') arabska+=50;else
if (rzym[i]=='V') arabska+=5;else
if (rzym[i]=='M') arabska+=1000;else
if (rzym[i]=='I')
{
if (i<strlen(rzym))
{
switch (rzym[i+1]){
case 'X': {arabska+=9;i++;break;}
case 'V': {arabska+=4;i++;break;}
default : {arabska+=1;break;}}
}else arabska+=1;
}else
if (rzym[i]=='C')
{
if (i+1<strlen(rzym))
{switch (rzym[i+1]){
case 'M': {arabska+=900;i++;break;}
case 'D': {arabska+=400;i++;break;}
default : {arabska+=100;break;}}
}else arabska+=100;
}else
if (rzym[i]=='X')
{
if (i+1<strlen(rzym))
{switch (rzym[i+1]){
case 'C': {arabska+=90;i++;break;}
case 'L': {arabska+=40;i++;break;}
default : {arabska+=10;break;}}
}else arabska+=10;
}
}
return arabska;
}
int main() {
if (yyparse())
fprintf(stderr, "Successful parsing.\n");
else
fprintf(stderr, "error found.\n");
}
plik flexa :
%{
#define YYSTYPE char
#include "kalkulator.tab.h"
#include <stdlib.h>
%}
white [ \t]+
rzymska [IVXLCDM]+
%%
{white} { }
{rzymska} {
return NUMBER;
}
"+" return PLUS;
"-" return MINUS;
"*" return TIMES;
"/" return DIVIDE;
"^" return POWER;
"(" return LEFT;
")" return RIGHT;
"\n" return END;