Вы находитесь на странице: 1из 21

1)Разработать транслятор для преобразования записи любой обыкновенной дроби с необязательным знаком в конечную десятичную дробь.

Записи обыкновенных дробей, в которых


числитель и знаменатель разделены символом '/', должны передаваться транслятору строками потока стандартного ввода. Результаты трансляции должны отображаться строками
потока стандартного вывода в формате десятичных дробей с фиксированной точкой.

LEX:

LINE "/"
%{
#include "y.tab.h"
extern int yylval;
%}

%%
^[+-]?(([1-9][0-9]*)|(0))/{LINE} {yylval=atoi(yytext); return NUM;}
\/[+-]?[0]$ {yylval=atoi(yytext+1);return DEN1;}
\/[+-]?([1-9][0-9]*)$ {yylval=atoi(yytext+1); return DEN;}
([a-zA-z]*[0-9]*)* {return ER;}
\n |
. ;

YACC:

%{
#include <stdio.h>
double k=0;
%}
%start list
%token NUM DEN DEN1 ER
%%
list:
|list drob;
drob: NUM DEN { k =(double)$1/$2; printf("Result=%f \n",k); return 0;}
|NUM DEN1 {printf("ZERO FAKE"); return 0;}
|NUM ER {printf("Error"); return 0;}
;
%%
int yyerror() {
printf("Error");
}
int yywrap() {
return 0;}
main() {
yyparse();
}

2)Разработать транслятор для преобразования записи любой конечной десятичной дроби с необязательным знаком в обыкновенную дробь. Все записи десятичных дробей должны
передаваться транслятору в формате с фиксированной точкой строками стандартного ввода. Результаты трансляции должны отображаться строками стандартного вывода, где
числители и знаменатели обыкновенных дробей разделены символом '/'.

LEX:

%{
#include <stdio.h>
#include "y.tab.h"
extern YYSTYPE yylval;
%}

%%
[-] {return MINUS;}
[0-9]+\.[0-9]+ {yylval.d=atof(yytext); return DIGIT;}
([a-z]*[A-z]*[0-9]*)* {return ER;}
\n |
.;

YACC:

%{
#include <stdio.h>
#include <math.h>
double l=0; int p;
%}
%union{
double d;
}
%start input
%token MINUS DIGIT ER PLUS
%type <d> DIGIT
%%
input: {printf("Enter");}
| input list
;
list: true
|error {
yyerrok;
yyclearin; }

;
true: DIGIT { p=power($1); trans(p,$1); return 0; }
| MINUS DIGIT { p=power(-1*$2); trans(p,-1*$2); return 0; }
| PLUS DIGIT { p=power($2); trans(p,$2); return 0; }
;

%%
int yyerror() { printf("Error77\n");}
int yywrap() {
return 0;}
int power (double n) {
if (n<0) n=n*-1;
n=n-(int)n;
//printf("n=%f\n",n);
char str[20];
sprintf(str,"%f", n);
//printf("vvv=%s\n",str);
int kol=0; int i;
for(i=7;str[i]=='0';i--) {
kol++;
}
kol=6-kol;
//printf("kol=%d\n",kol);
int znam=pow(10,kol);
//printf("znam=%d\n",znam);
return znam;
}

void trans(int z, double n) {


double n1;n1=n;
if(n<0) n1=-1*n;
double drob_chast; int nod;
drob_chast=n1-(int)n1; int chisl;
chisl=z*(int)n1+drob_chast*z;
//printf("chisl=%d\n",chisl);

nod=NOD(chisl,z);
if (n>0) {
printf("Answer %d/%d\n", chisl/nod, z/nod);
}
else
printf("Answer -%d/%d\n", chisl/nod, z/nod);

int NOD(int a, int b) {


while(a!=0 && b!=0) {
if(a>=b) a=a%b;
else b=b%a;
}
return a+b;
}

int main() { return yyparse(); }

3)
Разработать лексический анализатор для преобразования натуральных чисел, заданных римскими цифрами (I, V, X, L, C, D, M), в эквивалентную запись арабскими цифрами (0-9).
LEX:
%{
#include <stdio.h>
void print(char*,int);
int sign(char);
%}
%%
^M{0,3}(D?C{0,3}|C[DM])(L?X{0,3}|X[LC])(V?I{0,3}|I[VX])$ {print(yytext,yyleng);return 1;}
\n |
. {return 0;}
%%
int sign(char simb)
{
switch(simb)
{case('M'): return 1000;
case('D'): return 500;
case('C'): return 100;
case('L'): return 50;
case('X'): return 10;
case('V'): return 5;
case('I'): return 1;
}
}
void print(char *s,int num)
{
int i,res=0;
for(i=1;i<=num;)
{if(sign(s[i-1])<sign(s[i]))
{res+=sign(s[i])-sign(s[i-1]);i+=2;}
else
{res+=sign(s[i-1]);i++;}
}
printf("%s = %d\n",s,res);
}

4)
Разработать транслятор для преобразования записи любой обыкновенной дроби с необязательным знаком в сумму целой и правильной дробной части. Записи обыкновенных
дробей, где числитель и знаменатель разделены символом '/', должны передаваться транслятору строками потока стандартного ввода. Результаты трансляции должны отображаться
строками потока стандартного вывода, где целая и дробная части разделены знаком '+'.
LEX:
LINE "/"
%{
#include "y.tab.h"
extern int yylval;
%}
%%
^[+-]?(([1-9][0-9]*)|(0))/{LINE} {yylval=atoi(yytext); return NUM;}
\/[+-]?[0]$ {yylval=atoi(yytext+1); return DEN1;}
\/[+-]?([1-9][0-9]*)$ {yylval=atoi(yytext+1); return DEN;}
([a-zA-z]*[0-9]*)* {return ER;}
\n |
. ;

YACC:
%{
#include <stdio.h>
%}
%start list
%token NUM DEN1 DEN ER
%%
list:
|list drob;
drob: NUM DEN { trans($1,$2); return 0;}
|NUM DEN1 {printf("ZERO FAKE"); return 0;}
|NUM ER {printf("Error"); return 0;}
;
%%
int yyerror(){
printf("Error \n");}
int yywrap() {
return 0;
}

int NOD(int a, int b) {


while(a!=0 && b!=0) {
if(a>=b) a=a%b;
else b=b%a;
}
return a+b;
}

int trans(int a, int b) {


int c=0; int nod=0; double sn;
c=a/b;
sn=(double)a/b;
printf("sn=%f\n",sn);
a=a-b*c;

if(a<0) {a=a*-1;}
if(b<0) {b=b*-1;}
nod=NOD(a,b);
if(sn<=0) {
if(a==0) {
printf("Answer: -(%d + 0) \n", c*-1);
}
else
printf("-(%d+%d/%d)\n", c*-1,a/nod,b/nod);
}
else {
if (a==0) {
printf("%d+0\n",c);}
else {
printf("%d+%d/%d\n", c, a/nod, b/nod);}

}
}

main() {
yyparse();
}

5)
Разработать транслятор для преобразования записи любой обыкновенной дроби с необязательным знаком в разность целой и правильной дробной части. Записи обыкновенных
дробей, где числитель и знаменатель разделены символом '/', должны передаваться транслятору строками потока стандартного ввода. Результаты трансляции должны отображаться
строками потока стандартного вывода, где целая и дробная части разделены знаком ' '.
LEX:
LINE "/"
%{
#include "y.tab.h"
extern int yylval;
%}
%%
^[+-]?(([1-9][0-9]*)|(0))/{LINE} {yylval=atoi(yytext); return NUM;}
\/[+-]?[0]$ {yylval=atoi(yytext+1); return DEN1;}
\/[+-]?([1-9][0-9]*)$ {yylval=atoi(yytext+1); return DEN;}
([a-zA-z]*[0-9]*)* {return ER;}
\n |
. ;

YACC:
%{
#include <stdio.h>
%}
%start list
%token NUM DEN1 DEN ER
%%
list:
|list drob;
drob: NUM DEN { trans($1,$2); return 0;}
|NUM DEN1 {printf("ZERO FAKE"); return 0;}
|NUM ER {printf("Error"); return 0;}
;
%%
int yyerror(){
printf("Error \n");}
int yywrap() {
return 0;
}

int NOD(int a, int b) {


while(a!=0 && b!=0) {
if(a>=b) a=a%b;
else b=b%a;
}
return a+b;
}

int trans(int a, int b) {


int c=0; int nod=0; double sn;
c=a/b;
sn=(double)a/b;
printf("sn=%f\n",sn);
a=a-b*c;
if(a<0) {a=a*-1;}
if(b<0) {b=b*-1;}
nod=NOD(a,b);
if(sn<=0) {
if(a==0) {
printf("Answer: -(%d - 0) \n", c*-1);
}
else
printf("-(%d-%d/%d)\n", c*-1,a/nod,b/nod);
}
else {
if (a==0) {
printf("%d-0\n",c);}
else {
printf("%d-%d/%d\n", c, a/nod, b/nod);}

}
}
main() {
yyparse();
}

6)
Разработать транслятор для преобразования записи любой десятичной дроби с необязательным знаком в разность целой и дробной части. Записи десятичных дробей в любом
допустимом формате с фиксированной точкой должны передаваться транслятору строками потока стандартного ввода. Результаты трансляции должны отображаться строками
потока стандартного вывода, где целая и дробная части разделены знаком ' '.
LEX:
DOT "."
%{
#include"y.tab.h"
%}
%%
^[+]/{DOT} {yylval=strdup(yytext); return SGN;}
^[-]([1-9][0-9]*)/{DOT} {yylval=strdup(yytext); return CEL;}
^[+]?(([1-9][0-9]*)|[0])/{DOT} {yylval=strdup(yytext); return CEL;}
^[-]/{DOT} {yylval=strdup(yytext); return SGNM;}
^[-][0]/{DOT} {yylval=strdup(yytext); return CELM;}
\.([0-9]*)$ {yylval=strdup(yytext+1); return DRB;}
([a-zA-z ]*[0-9]*)* {return ER;}
\n |
. ;

YACC:

%{
#include <stdio.h>
#include <string.h>
#define YYSTYPE char *
int a=0, b=0, c=0;
int trans(int a, int b, int c);
int transM(int a, int b, int c);
%}
%start list
%token CEL DRB SGN CELM SGNM ER
%%
list:
|list drob
;

drob: CEL DRB {a=strlen($2); b=atoi($1); c=atoi($2); trans(a,b,c); return 0;}


|CELM DRB {a=strlen($2); b=0; c=atoi($2); transM(a,b,c); return 0;}
|SGN DRB {a=strlen($2); b=atoi($1); c=atoi($2); trans(a,b,c); return 0;}
|SGNM DRB {a=strlen($2); b=0; c=atoi($2); transM(a,b,c); return 0;}
|DRB {a=strlen($1); b=0; c=atoi($1); trans(a,b,c); return 0;}
|CEL ER {puts("ERROR"); return 0;}
;
%%
int yyerror()
{puts("ERROR");}
int yywrap()
{return 0;}
int trans(int a, int b, int c)
{
int i=0, k=1, num=0;
double drb=0.0;
for(i=0;i<a;i++)
{k=k*10;}
drb=(double)c/k;
if(b<0)
{printf("Result = -( %d - %.3f)\n",b*-1+1,1-drb);}
else
{printf("Result = %d - %.3f\n",b+1,1-drb);}
}
int transM(int a, int b, int c)
{
int i=0, k=1;
double drb=0.0;
for(i=0;i<a;i++)
{k=k*10;}
drb=(double)c/k;
printf("Result = -( %d - %.3f)\n",b+1,1-drb);
}
main()
{yyparse();}

7)
Разработать транслятор для преобразования записи любой десятичной дроби с необязательным знаком в сумму ее целой и дробной части. Записи десятичных дробей в любом
допустимом формате с фиксированной точкой должны передаваться транслятору строками потока стандартного ввода. Результаты трансляции должны отображаться строками
потока стандартного вывода, где целая и дробная части разделены знаком '+'.
LEX:
DOT "."
%{
#include"y.tab.h"
%}
%%
^[+]/{DOT} {yylval=strdup(yytext); return SGN;}
^[-]([1-9][0-9]*)/{DOT} {yylval=strdup(yytext); return CEL;}
^[+]?(([1-9][0-9]*)|[0])/{DOT} {yylval=strdup(yytext); return CEL;}
^[-]/{DOT} {yylval=strdup(yytext); return SGNM;}
^[-][0]/{DOT} {yylval=strdup(yytext); return CELM;}
\.([0-9]*)$ {yylval=strdup(yytext+1); return DRB;}
([a-zA-z ]*[0-9]*)* {return ER;}
\n |
. ;

YACC:
%{
#include <stdio.h>
#include <string.h>
#define YYSTYPE char *
int a=0, b=0, c=0;
int trans(int a, int b, int c);
int transM(int a, int b, int c);
%}
%start list
%token CEL DRB SGN CELM SGNM ER
%%
list:
|list drob
;
drob: CEL DRB {a=strlen($2); b=atoi($1); c=atoi($2); trans(a,b,c); return 0;}
|CELM DRB {a=strlen($2); b=0; c=atoi($2); transM(a,b,c); return 0;}
|SGN DRB {a=strlen($2); b=atoi($1); c=atoi($2); trans(a,b,c); return 0;}
|SGNM DRB {a=strlen($2); b=0; c=atoi($2); transM(a,b,c); return 0;}
|DRB {a=strlen($1); b=0; c=atoi($1); trans(a,b,c); return 0;}
|CEL ER {puts("ERROR"); return 0;}
;
%%
int yyerror()
{puts("ERROR");}
int yywrap()
{return 0;}
int trans(int a, int b, int c)
{
int i=0, k=1, num=0;
double drb=0.0;
for(i=0;i<a;i++)
{k=k*10;}
drb=(double)c/k;
if(b<0)
{printf("Result = -( %d + %.3f)\n",b*-1,drb);}
else
{printf("Result = %d + %.3f\n",b,drb);}
}
int transM(int a, int b, int c)
{
int i=0, k=1;
double drb=0.0;
for(i=0;i<a;i++)
{k=k*10;}
drb=(double)c/k;
printf("Result = -( %d + %.3f)\n",b,drb);
}
main()
{yyparse();}

8)
Разработать транслятор для округления значения любой обыкновенной дроби с необязательным знаком до наибольшего целого числа, которое не превосходит ее величину. Записи
обыкновенных дробей, в которых числитель и знаменатель разделены символом '/', должны передаваться транслятору строками потока стандартного ввода.
Результаты трансляции должны отображаться строками целых чисел в потоке стандартного вывода.
LEX:
LINE "/"
%{
#include"y.tab.h"
%}
%%
^[+-]?(([1-9][0-9]*)|(0))/{LINE} {yylval=atoi(yytext); return NUM;}
\/[+-]?[0]$ {yylval=atoi(yytext+1); return DEN1;}
\/[+-]?([1-9][0-9]*)$ {yylval=atoi(yytext+1); return DEN;}
([a-zA-z ]*[0-9]*)* {return ER;}
\n |
. ;

YACC:
%{
#include <stdio.h>
int trans(int a, int b);
%}
%start list
%token NUM DEN DEN1 ER
%%
list:
|list drob
;
drob: NUM DEN {trans($1, $2); return 0;}
|NUM DEN1 {puts("ZERO FAKE"); return 0;}
|NUM ER {puts("ERROR"); return 0;}
;
%%
int yyerror()
{puts("ERROR");}
int yywrap()
{return 0;}
int trans(int a, int b)
{
int c=0;
double sn=0.0;
c=a/b;
sn=(double)a/b;;
if(sn<0)
{
if(a!=0 && a%b==0)
{printf("Result = %d\n", c+1);}
else
{printf("Result = %d\n", c);}
}
else
{printf("Result = %d\n", c+1);}
}
main()
{yyparse();}

9)
Разработать транслятор для преобразования алгебраического формата записи комплексных чисел в эквивалентную тригонометрическую форму. Входные записи любых
комплексных чисел, где мнимая и действительная части заданы обыкновенными дробями, в которых числитель и знаменатель разделяет символ '/', должны передаваться
транслятору строками стандартного ввода. Результаты трансляции должны отображать строки стандартного вывода, где модули и аргументы комплексных чисел, заданы
десятичными дробями.

LEX:
%{
#include<stdio.h>
#include"y.tab.h"
%}
%Start NOM IM
%%
^[-]?([0]|[1-9][0-9]*)/\/ {yylval=atoi(yytext);BEGIN NOM;return RENM;}
<IM>[+-]([0]|[1-9][0-9]*)/\/ {yylval=atoi(yytext);BEGIN NOM;return IMNM;}
<NOM>[0] {return ZERO;}
\/ {return '/';}
<NOM>[1-9][0-9]*/(j\n) {yylval=atoi(yytext);return IMDNM;}
<NOM>[1-9][0-9]*/[+-] {BEGIN IM; yylval=atoi(yytext);return REDNM;}
\n |
. {return 0;}

YACC:
%{
#include <stdio.h>
#include <math.h>
#include <ctype.h>
void trans(double ,double ,
double *, double *);
double arg, fi, im1,re1;
%}
%token RENM IMNM REDNM IMDNM ZERO
%%
complex: real image
{trans(re1,im1,&arg,&fi);
printf("%.3f*(cos(%.3f)+j*sin(%.3f))\n",
arg,fi,fi);}
real: RENM '/' REDNM {
re1=(double)$1/$3;}
| RENM '/' ZERO {
puts("ZERO FAKE");return 0;}
image: IMNM '/'IMDNM {
im1=(double)$1/$3;}
| IMNM '/' ZERO {
puts("ZERO FAKE");return 0;}
%%
int yyerror(char*s)
{puts(s);}
void trans(double re,double im,
double *farg,double *ffi)
{
if(!re)
{*farg=im;*ffi=3.14;return;}
if(!im)
{*farg=re;*ffi=0;return;}
*farg=pow(re*re+im*im,0.5);
*ffi=atan(im/re);
}
main()
{yyparse();}

10)
Разработать транслятор для преобразования алгебраического формата записи комплексных чисел в эквивалентную тригонометрическую форму. Входные записи любых
комплексных чисел должны передаваться транслятору строками потока стандартного ввода, а результаты трансляции должны отображать строки потока стандартного вывода. При
этом любые численные значения во входных и выходных записях комплексных чисел должны быть заданы обыкновенными дробями, где числитель и знаменатель разделены
символом '/'.
LEX:
%{
#include<stdio.h>
#include"y.tab.h"
#define YYSTYPE
extern YYSTYPE yylval;
%}
%Start NOM IM
%%
^[-]?([0]|[1-9][0-9]*)/\/ {yylval=atoi(yytext);BEGIN NOM;return RENM;}
<IM>[+-]([0]|[1-9][0-9]*)/\/ {yylval=atoi(yytext);BEGIN NOM;return IMNM;}
<NOM>[0] {return ZERO;}
\/ {return '/';}
<NOM>[1-9][0-9]*/(j\n) {yylval=atoi(yytext);return IMDNM;}
<NOM>[1-9][0-9]*/[+-] {BEGIN IM; yylval=atoi(yytext);return REDNM;}
\n |
. {return 0;}

YACC:
%{
#include <stdio.h>
#include <math.h>
#include<ctype.h>
#define ST 1000
void drob(double,int*,int*);
void trans(double ,double ,double *, double *);
double arg, fi, im1,re1;
int fn,fd,an,ad;
%}
%token RENM IMNM REDNM IMDNM ZERO
%%
complex: real image
{trans(re1,im1,&arg,&fi);
drob(arg,&an,&ad);
drob(fi,&fn,&fd);
printf("%d/%d*(cos(%d/%d)+j*sin(%d/%d))\n",
an,ad,fn,fd,fn,fd);}
real: RENM '/' REDNM {re1=(double)$1/$3;}
| RENM '/' ZERO {puts("ZERO FAKE");return 0;}
image: IMNM '/'IMDNM {im1=(double)$1/$3;}
| IMNM '/' ZERO {puts("ZERO FAKE");return 0;}
%%
int yyerror(char*s)
{puts(s);}
int yywrap() {
return 0;}
void drob(double num,int *fnm,int *fdnm)
{
int a,b,p;
*fnm=(int)(num*ST);
*fdnm=ST;
for(a=abs(*fnm),b=abs(*fdnm);a*b;)
{ if(a>=b) a=a%b;
else b=b%a;
}
p=a+b;
*fnm/=p;
*fdnm/=p;
}
void trans(double re,double im,double *farg,
double *ffi)
{
if(!re)
{*farg=im;*ffi=3.14;return;}
if(!im)
{*farg=re;*ffi=0;return;}
*farg=pow(re*re+im*im,0.5);
*ffi=atan(im/re);
}
main()
{yyparse();}

11)
Разработать транслятор для округления значения любой обыкновенной дроби с необязательным знаком до наибольшего(может быть наименьшего, я ХЗ) целого числа, которое не
превосходит ее величину. Записи обыкновенных дробей, в которых числитель и знаменатель разделены символом '/', должны передаваться транслятору строками потока
стандартного ввода. Результаты трансляции должны отображаться строками целых чисел в потоке стандартного вывода.
LEX:
LINE "/"
%{
#include"y.tab.h"
extern int yylval;
%}

%%

^[+-]?(([1-9][0-9]*)|(0))/{LINE} {yylval=atoi(yytext); return NUM;}


\/[+-]?[0]$ {yylval=atoi(yytext+1); return DEN1;}
\/[+-]?([1-9][0-9]*)$ {yylval=atoi(yytext+1); return DEN;}
([a-zA-z ]*[0-9]*)* {return ER;}
\n |
. ;

YACC:
%{
//lex t01
#include <stdio.h>
int trans(int a, int b);
%}
%start list
%token NUM DEN DEN1 ER

%%

list:
|list drob
;

drob: NUM DEN {trans($1, $2); return 0;}


|NUM DEN1 {puts("ZERO FAKE"); return 0;}
|NUM ER {puts("ERROR"); return 0;}
;

%%

int yyerror()
{puts("ERROR");}

int yywrap()
{return 0;}

int trans(int a, int b)


{
int c=0;
double sn=0.0;
c=a/b;
sn=(double)a/b;;

if(sn<0)
{
if(a!=0 && a%b==0)
{printf("Result = %d\n", c+1);}
else
{printf("Result = %d\n", c);}
}
else
{printf("Result = %d\n", c+1);}
}

main()
{yyparse();}

12)
Разработать транслятор для округления любой конечной десятичной дроби с необязательным знаком до наибольшего(может наименьшего) целого числа, которое не
превосходит ее по величине. Записи десятичных дробей должны передаваться транслятору в экспоненциальной форме строками потока стандартного ввода.
Результаты трансляции должны отображаться строками целых чисел в потоке стандартного вывода.

LEX:
DOT "."
%{
#include"y.tab.h"
%}

%%

^[+]/{DOT} {yylval=strdup(yytext); return SGN;}


^[-]([1-9][0-9]*)/{DOT} {yylval=strdup(yytext); return CEL;}
^[+]?(([1-9][0-9]*)|[0])/{DOT} {yylval=strdup(yytext); return CEL;}
^[-]/{DOT} {yylval=strdup(yytext); return SGNM;}
^[-][0]/{DOT} {yylval=strdup(yytext); return CELM;}
\.([0-9]*)/[eE] {yylval=strdup(yytext+1); return DRB;}
[eE][-+][0-9]{1,2}$ {yylval=strdup(yytext+1); return STP;}
([a-zA-z ]*[0-9]*)* {return ER;}
\n |
. ;

YACC:
%{
//lex t09
#include <stdio.h>
#include <string.h>
#define YYSTYPE char *
int a=0, b=0, c=0, stp=0;
int trans(int a, int b, int c, int stp);
int transM(int a, int b, int c, int stp);
%}
%start list
%token CEL DRB SGN CELM SGNM STP ER

%%

list:
|list drob
;

drob: CEL DRB STP {a=strlen($2); b=atoi($1); c=atoi($2); stp=atoi($3); trans(a,b,c,stp); return 0;}
|CELM DRB STP {a=strlen($2); b=0; c=atoi($2); stp=atoi($3); transM(a,b,c,stp); return 0;}
|SGN DRB STP {a=strlen($2); b=atoi($1); c=atoi($2); stp=atoi($3); trans(a,b,c,stp); return 0;}
|SGNM DRB STP {a=strlen($2); b=0; c=atoi($2); stp=atoi($3); transM(a,b,c,stp); return 0;}
|DRB STP {a=strlen($1); b=0; c=atoi($1); stp=atoi($2); trans(a,b,c,stp); return 0;}
;

%%

int yyerror()
{puts("ERROR");}

int yywrap()
{return 0;}

int trans(int a, int b, int c, int stp)


{
int i=0, k=1, f=0, cel=0;
double drb=0.0, sp=1.0;
for(i=0;i<a;i++)
{k=k*10;}
if(b<0)
{b=b*-1;drb=b+(double)c/k;f=1;}
else{drb=b+(double)c/k;}
if(stp>0)
{for(i=0;i<stp;i++)
{sp=sp*10;}}
else
{stp=stp*-1;
for(i=0;i<stp;i++)
{sp=sp/10;}}
if(f)
{drb=drb*sp*-1;
cel=(int)drb;
if((int)((double)c/sp)==0)
{cel=cel+1;}}
else
{drb=drb*sp;
cel=(int)drb+1;}
printf ("Result = %d\n",cel);
}

int transM(int a, int b, int c, int stp)


{
int i=0, k=1, cel=0;
double drb=0.0, sp=1.0;
for(i=0;i<a;i++)
{k=k*10;}
drb=b+(double)c/k;
if(stp>0)
{for(i=0;i<stp;i++)
{sp=sp*10;}}
else
{stp=stp*-1;
for(i=0;i<stp;i++)
{sp=sp/10;}}
drb=drb*sp*-1;
cel=(int)drb;
if((int)((double)c/sp)==0)
{cel=cel+1;}
printf ("Result = %d\n",cel);}

main()
{yyparse();}

13)
Разработать транслятор для преобразования алгебраического формата записи комплексных чисел в эквивалентную тригонометрическую форму. Входные записи любых
комплексных чисел должны передаваться транслятору строками потока стандартного ввода. Результаты трансляции должны отображать строки потока стандартного вывода. При
этом любые численные значения во входных и выходных записях комплексных чисел должны быть заданы десятичными дробями.
LEX:
%{
#define A 258
#define B 259
#define ENTER 260
#include <string.h>
char tmp[256];
extern double num_A;
extern double num_B;
extern short c;
%};

%%
-?[0-9]+"."[0-9]+ { c=0;
num_A=atoi(yytext);
return A;
}
[+-]?[0-9]+"."[0-9]+i {

c=1;
strncpy(tmp,yytext,(strlen(yytext)-1));
tmp[strlen(yytext)]='\0';
num_B=atof(tmp);
if ((yytext[0]=='-')&&(yytext[1]=='i'))
num_B=-1;
if ((yytext[0]=='i')||((yytext[0]=='+')&&(yytext[1]=='i')))
num_B=1;

return B;
}
\n return ENTER;
.;

YACC:
%start make
%token A B ENTER

%{
#include <stdio.h>
#include <string.h>
#include "math.h"
#include "stdlib.h"

double num_A, num_B;


double r,f;
short c;
void translate();
%}

%%
make:A B ENTER{translate();}
|A ENTER{translate();}
|B ENTER{translate();}
|make A B ENTER{translate();}
|make A ENTER{translate();}
|make B ENTER{translate();};
%%
void translate()
{
r=sqrt(num_A*num_A+num_B*num_B);
if(c==0||num_B==0) { printf("%4.2f\n",r); return; }
f=asin(num_B/r);
printf("%4.2f*(cos(%4.2f)+i*sin(%4.2f))\n",r,f,f);
r=0; f=0; num_A=0; num_B=0;
}

yyerror()
{
return 0;
}
yywrap()
{
return 1;
}

main ()
{
yyparse();
}

14) Разработать транслятор для преобразования записи любого вещественного числа, которое задано в формате с фиксированной точкой, в экспоненциальную форму без дробной
части. Записи вещественных чисел должны передаваться транслятору строками стандартного ввода. Результаты трансляции должны отображаться строками стандартного вывода.
При этом записи вещественных чисел должны соответствовать формату констант системы программирования С.
LEX:

DOT "."
%{
#include"y.tab.h"
#include <string.h>
#include <math.h>
#define YYSTYPE char *
extern YYSTYPE yylval;
%}

%%

^[+]/{DOT} {yylval=strdup(yytext); return SGN;}


^[-]([1-9][0-9]*)/{DOT} {yylval=strdup(yytext); return CEL;}
^[+]?(([1-9][0-9]*)|[0])/{DOT} {yylval=strdup(yytext); return CEL;}
^[-]/{DOT} {yylval=strdup(yytext); return SGNM;}
^[-][0]/{DOT} {yylval=strdup(yytext); return CELM;}
\.([0-9]*)$ {yylval=strdup(yytext+1); return DRB;}
([a-zA-z ]*[0-9]*)* {return ER;}
\n |
. ;

YACC:
%{
//lex t02
#include <stdio.h>
#include <string.h>
#include <math.h>
#define YYSTYPE char *
int a=0, b=0, c=0;
int trans(int a, int b, int c);
int transM(int a, int b, int c);
%}
%start list
%token CEL DRB SGN CELM SGNM ER

%%

list:
|list drob
;

drob: CEL DRB {a=strlen($2); b=atoi($1); c=atoi($2); trans(a,b,c); return 0;}


|CELM DRB {a=strlen($2); b=0; c=atoi($2); transM(a,b,c); return 0;}
|SGN DRB {a=strlen($2); b=atoi($1); c=atoi($2); trans(a,b,c); return 0;}
|SGNM DRB {a=strlen($2); b=0; c=atoi($2); transM(a,b,c); return 0;}
|DRB {a=strlen($1); b=0; c=atoi($1); trans(a,b,c); return 0;}
|CEL ER {puts("ERROR"); return 0;}
;

%%

int yyerror()
{puts("ERROR");}

int yywrap()
{return 0;}

int trans(int a, int b, int c)


{
int i=0, k=1, num=0;
for(i=0;i<a;i++)
{k=k*10;}
b=b*k+c;

if(b<0)
{printf("Result = - %de-0%d\n",b*-1,a);}
else
{printf("Result = %de-0%d\n",b,a);}
}

int transM(int a, int b, int c)


{
int i=0, k=1;
for(i=0;i<a;i++)
{k=k*10;}
b=b*k+c;
printf("Result = - %de-0%d\n",b,a);
}

main()
{yyparse();}

15)
Разработать транслятор для преобразования записи любого вещественного числа, которое задано в экспоненциальной форме, в формат с фиксированной точкой. Входные записи
вещественных чисел должны передаваться транслятору строками стандартного ввода. Результаты трансляции должны отображаться строками стандартного вывода. При этом все
записи вещественных чисел должны соответствовать формату констант системы программирования С.

LEX:

DOT "."
%{
#include"y.tab.h"
#include <string.h>
#include <math.h>
#define YYSTYPE char *
extern YYSTYPE yylval;
%}

%%
^[+]/{DOT} {yylval=strdup(yytext); return SGN;}
^[-]([1-9][0-9]*)/{DOT} {yylval=strdup(yytext); return CEL;}
^[+]?(([1-9][0-9]*)|[0])/{DOT} {yylval=strdup(yytext); return CEL;}
^[-]/{DOT} {yylval=strdup(yytext); return SGNM;}
^[-][0]/{DOT} {yylval=strdup(yytext); return CELM;}
\.([0-9]*)/[eE] {yylval=strdup(yytext+1); return DRB;}
[eE][-+][0-9]{1,2}$ {yylval=strdup(yytext+1); return STP;}
([a-zA-z ]*[0-9]*)* {return ER;}
\n |
. ;

YACC:
%{
//lex t09
#include <stdio.h>
#include <string.h>
#define YYSTYPE char *
int a=0, b=0, c=0, stp=0;
int trans(int a, int b, int c, int stp);
int transM(int a, int b, int c, int stp);
%}
%start list
%token CEL DRB SGN CELM SGNM STP ER

%%

list:
|list drob
;

drob: CEL DRB STP {a=strlen($2); b=atoi($1); c=atoi($2); stp=atoi($3); trans(a,b,c,stp); return 0;}
|CELM DRB STP {a=strlen($2); b=0; c=atoi($2); stp=atoi($3); transM(a,b,c,stp); return 0;}
|SGN DRB STP {a=strlen($2); b=atoi($1); c=atoi($2); stp=atoi($3); trans(a,b,c,stp); return 0;}
|SGNM DRB STP {a=strlen($2); b=0; c=atoi($2); stp=atoi($3); transM(a,b,c,stp); return 0;}
|DRB STP {a=strlen($1); b=0; c=atoi($1); stp=atoi($2); trans(a,b,c,stp); return 0;}
;

%%

int yyerror()
{puts("ERROR");}

int yywrap()
{return 0;}

int trans(int a, int b, int c, int stp)


{
int i=0, k=1, f=0;
double drb=0.0, sp=1.0;
for(i=0;i<a;i++)
{k=k*10;}
if(b<0)
{b=b*-1;drb=b+(double)c/k;f=1;}
else{drb=b+(double)c/k;}
if(stp>0)
{for(i=0;i<stp;i++)
{sp=sp*10;}}
else
{stp=stp*-1;
for(i=0;i<stp;i++)
{sp=sp/10;}}
if(f)
{drb=drb*sp*-1;}
else
{drb=drb*sp;}
printf ("Result = %.5f\n",drb);
}

int transM(int a, int b, int c, int stp)


{
int i=0, k=1;
double drb=0.0, sp=1.0;
for(i=0;i<a;i++)
{k=k*10;}
drb=b+(double)c/k;
if(stp>0)
{for(i=0;i<stp;i++)
{sp=sp*10;}}
else
{stp=stp*-1;
for(i=0;i<stp;i++)
{sp=sp/10;}}
drb=drb*sp*-1;
printf ("Result = %.5f\n",drb);}

main()
{yyparse();}

16)
Разработать транслятор для преобразования записи любой обыкновенной дроби с необязательным знаком в конечную десятичную дробь. Записи обыкновенных дробей, в которых
числитель и знаменатель разделены символом '/', должны передаваться транслятору строками потока стандартного ввода. Результаты трансляции должны отображаться строками
потока стандартного вывода в формате десятичных дробей с фиксированной точкой.

LEX:
%{
int yylval;
#include"y.tab.h"
%}

%%
^[+-]?(([1-9][0-9]*)|(0))/"/" {yylval=atoi(yytext); return NUM;}
\/[+-]?[0]$ {yylval=atoi(yytext+1); return DEN1;}
\/[+-]?([1-9][0-9]*)$ {yylval=atoi(yytext+1); return DEN;}
([a-zA-Z ]*[0-9]*)* {return ER;}
. ;
YACC:

%{
#include <stdio.h>
%}
%start list
%token NUM DEN DEN1 ER
%%
list:
|list drob
;
drob: NUM DEN {printf("Result = %.3E\n",(double)$1/$2); return 0;}
|NUM DEN1 {puts("Division by zero"); return 0;}
|NUM ER {puts("ERROR"); return 0;}
;
%%

int yyerror()
{puts("ERROR");}
int yywrap()
{return 0;}
main() {yyparse();}

17)
Разработать транслятор для преобразования записи любой конечной десятичной дроби с необязательным знаком в обыкновенную дробь. Все десятичные дроби должны
передаваться транслятору в экспоненциальном формате записи вещественных чисел через строки потока стандартного ввода. Результаты трансляции должны отображаться
строками потока стандартного вывода, где числители и знаменатели обыкновенных дробей разделены символом '/'.

LEX:

DOT "."
%{
#include"y.tab.h"
%}
%%
^[+]/{DOT} {yylval=strdup(yytext); return SGN;}
^[-]([1-9][0-9]*)/{DOT} {yylval=strdup(yytext); return CEL;}
^[+]?(([1-9][0-9]*)|[0])/{DOT} {yylval=strdup(yytext); return CEL;}
^[-]/{DOT} {yylval=strdup(yytext); return SGNM;}
^[-][0]/{DOT} {yylval=strdup(yytext); return CELM;}
\.([0-9]*)/[eE] {yylval=strdup(yytext+1); return DRB;}
[eE][-+][0-9]{1,2}$ {yylval=strdup(yytext+1); return STP;}
([a-zA-z ]*[0-9]*)* {return ER;}
\n |
. ;

YACC:

%{
#include <stdio.h>
#include <string.h>
#define YYSTYPE char *
int a=0, b=0, c=0, stp=0;
int trans(int a, int b, int c, int stp);
int transM(int a, int b, int c, int stp);
%}
%start list
%token CEL DRB SGN CELM SGNM STP ER
%%
list:
|list drob
;
drob: CEL DRB STP {a=strlen($2); b=atoi($1); c=atoi($2); stp=atoi($3); trans(a,b,c,stp); return 0;}
|CELM DRB STP {a=strlen($2); b=0; c=atoi($2); stp=atoi($3); transM(a,b,c,stp); return 0;}
|SGN DRB STP {a=strlen($2); b=atoi($1); c=atoi($2); stp=atoi($3); trans(a,b,c,stp); return 0;}
|SGNM DRB STP {a=strlen($2); b=0; c=atoi($2); stp=atoi($3); transM(a,b,c,stp); return 0;}
|DRB STP {a=strlen($1); b=0; c=atoi($1); stp=atoi($2); trans(a,b,c,stp); return 0;}
;
%%
int yyerror()
{puts("ERROR");}

int yywrap()
{return 0;}

int trans(int a, int b, int c, int stp)


{
int i=0, k=1, f=0;
double drb=0.0, sp=1.0;
for(i=0;i<a;i++)
{k=k*10;}
if(b<0)
{b=b*-1;drb=b+(double)c/k;f=1;}
else{drb=b+(double)c/k;}
if(stp>0)
{for(i=0;i<stp;i++)
{sp=sp*10;}}
else
{stp=stp*-1;
for(i=0;i<stp;i++)
{sp=sp/10;}}
if(f)
{drb=drb*sp*-1;}
else
{drb=drb*sp;}
if(k/sp<1)
{printf ("Result = %.0f/%.0f\n",drb*sp/k, sp/k);}
else
{printf ("Result = %.0f/%.0f\n",drb*k/sp, k/sp);}
}
int transM(int a, int b, int c, int stp)
{
int i=0, k=1;
double drb=0.0, sp=1.0;
for(i=0;i<a;i++)
{k=k*10;}
drb=b+(double)c/k;
if(stp>0)
{for(i=0;i<stp;i++)
{sp=sp*10;}}
else
{stp=stp*-1;
for(i=0;i<stp;i++)
{sp=sp/10;}}
drb=drb*sp*-1;
if(k/sp<1)
{printf ("Result = %.0f/%.0f\n",drb*sp/k, sp/k);}
else
{printf ("Result = %.0f/%.0f\n",drb*k/sp, k/sp);}
}
main(){yyparse();}
18)
Разработать транслятор для преобразования записи любой периодической десятичной дроби в обыкновенную дробь. Записи периодических десятичных дробей должны
передаваться транслятору строками стандартного ввода в формате вещественных чисел с фиксированной точкой, где период указан в круглых скобках. Результаты трансляции
должны отображаться строками стандартного вывода, где числители и знаменатели обыкновенных дробей разделены символом '/'.

LEX:
%{
#include "y.tab.h"
int yylval;
%}

%%
[-](([1-9][0-9]*)|[0])/"." {yylval=-atoi(yytext); return NUMB1;}
^(([1-9][0-9]*)|[0])/"." {yylval=atoi(yytext); return NUMB;}
([0-9]+)/"(" {yylval=atoi(yytext); return PART;}
([1-9][0-9]*)/")" {yylval=atoi(yytext); return PERIOD;}
([a-zA-Z ]*[0-9]*)* {return ER;}
.|
\n

%%

YACC:
%{
#include <stdio.h>
%}

%token NUMB PART PERIOD ER NUMB1


%start list
%%

list:
|list drob sep
;
drob: NUMB PART PERIOD { trans1($1,$2,$3); return 0;}
| NUMB1 PART PERIOD {trans3($1,$2,$3); return 0;}
| NUMB PERIOD {trans2($1,$2); return 0;}
| NUMB ER PERIOD {puts("ERROR"); return 0;}
| ER PERIOD {puts("ERROR"); return 0;}
| ER PART PERIOD {puts("ERROR"); return 0;}
| ER ER {puts("ERROR"); return 0;}
;

sep:
|' '
|'\n'
|'\t'
;

%%
int yyerror(const char *str)
{
{puts("ERROR");}
}
int yywrap()
{
return 1;
}

int trans2(int a, int b)


{
int d=0, c=0, nod=0;
c=b;
while(c>0)
{c=c/10;
d=d*10+9;}
nod=NOD(b,d);
d=d/nod;
b=b/nod;
b=a*d+b;
printf("Here comes the Magic: %d/%d\n",b,d);
}

int trans1(int a, int b, int c)


{
int d=0,e=0, nod=0, i=0;
e=c;
while(e>0)
{e=e/10;
d=d*10+9;
i++;}
e=b;
while(e>0)
{e=e/10;
d=d*10;
}
e=b;
while(i>0)
{e=e*10;
i--;}
c=e+c;
c=c-b;
nod=NOD(c,d);
d=d/nod;
c=c/nod;
c=a*d+c;
printf("Here comes the Magic: %d/%d\n",c,d);
}

int trans3(int a, int b, int c)


{
int d=0,e=0, nod=0, i=0;
e=c;
while(e>0)
{e=e/10;
d=d*10+9;
i++;}
e=b;
while(e>0)
{e=e/10;
d=d*10;
}
e=b;
while(i>0)
{e=e*10;
i--;}
c=e+c;
c=c-b;
nod=NOD(c,d);
d=d/nod;
c=c/nod;
c=a*d+c;
printf("Here comes the Magic: -%d/%d\n",c,d);
}

int NOD(int a,int b)


{
while(a!=0 && b!=0)
{
if(a>=b) a=a%b;
else b=b%a;
}
return a+b;
}

int main(){yyparse();}

19)
Разработать транслятор для преобразования алгебраического формата записи комплексных чисел в эквивалентную тригонометрическую форму. Входные записи любых
комплексных чисел, где мнимая и действительная части заданы целыми числами, должны передаваться транслятору строками стандартного ввода. Результаты трансляции должны
отображать строки стандартного вывода, а модули и аргументы комплексных чисел, заданы обыкновенными дробями, где числитель и знаменатель разделены символом '/'.

LEX:
%{
#include<stdio.h>
#include"y.tab.h"
int yylval;
%}

%%
^[-]?([0]|[1-9][0-9]*) {yylval=atoi(yytext);return REA;}
[+-]([0]|[1-9][0-9]*)/(j\n) {yylval=atoi(yytext);return IMA;}
[0] {return ZERO;}
\n |
. {return 0;}

YACC:

%{
#include <stdio.h>
#include <math.h>
#include <ctype.h>
#define ST 1000
double f1,f2;
void func(double ,double, double *,double *);
void drob(double,int*,int*);
int fn,fd,an,ad;
%}
%token REA IMA ZERO
%%
complex: REA IMA {func($1,$2,&f1,&f2);drob(f1,&an,&ad);drob(f2,&fn,&fd);printf("%d/%d*(cos(%d/%d)+j*sin(%d/%d))\n",an,ad,fn,fd,fn,fd);return 0;}
%%

int yyerror(char*s)
{puts(s);}

void func(double re, double im,double *ff1,double *ff2)


{
if((!re)&&(!im))
{
*ff1=0;*ff2=0;return;
}
if(!re)
{
*ff1=im;*ff2=3.14;return;
}
if(!im)
{
*ff1=re;*ff2=0;return;
}
*ff1=pow(re*re+im*im,0.5);
*ff2=atan(im/re);
}

void drob(double num,int *fnm,int *fdnm)


{
int a,b,p;
*fnm=(int)(num*ST);
*fdnm=ST;
for(a=abs(*fnm),b=abs(*fdnm);a*b;)
{
if(a>=b) a=a%b;
else b=b%a;
}
p=a+b;
*fnm/=p;
*fdnm/=p;
}

main() {yyparse();}

20)
Разработать транслятор для преобразования алгебраического формата записи комплексных чисел в эквивалентную тригонометрическую форму. Входные записи любых
комплексных чисел, где мнимая и действительная части заданы обыкновенными дробями, в которых числитель и знаменатель разделяет символ '/', должны передаваться
транслятору строками стандартного ввода. Результаты трансляции должны отображать строки стандартного вывода, где модули и аргументы комплексных чисел, заданы
десятичными дробями.

Компилить с тегами -lfl -lm.

LEX:
%{
#include<stdio.h>
#include"y.tab.h"
%}
%Start NOM IM
%%
^[-]?([0]|[1-9][0-9]*)/\/ {yylval=atoi(yytext);BEGIN NOM;return RENM;}
<IM>[+-]([0]|[1-9][0-9]*)/\/ {yylval=atoi(yytext);BEGIN NOM;return IMNM;}
<NOM>[0] {return ZERO;}
\/ {return '/';}
<NOM>[1-9][0-9]*/(j\n) {yylval=atoi(yytext);return IMDNM;}
<NOM>[1-9][0-9]*/[+-] {BEGIN IM; yylval=atoi(yytext);return REDNM;}
\n |
. {return 0;}

YACC:
%{
#include <stdio.h>
#include <math.h>
#include<ctype.h>
void trans(double ,double ,double *,
double *);
double arg, fi, im1,re1;
%}
%token RENM IMNM REDNM IMDNM ZERO
%%
complex: real image
{trans(re1,im1,&arg,&fi);
printf("%.3f*(cos(%.3f)+j*sin(%.3f))\n",
arg,fi,fi);}
real: RENM '/' REDNM {
re1=(double)$1/$3;}
| RENM '/' ZERO {
puts("ZERO FAKE");return 0;}
image: IMNM '/'IMDNM {
im1=(double)$1/$3;}
| IMNM '/' ZERO {
puts("ZERO FAKE");return 0;}
%%
int yyerror(char*s)
{puts(s);}
void trans(double re,double im,
double *farg, double *ffi)
{
if(!re)
{*farg=im;*ffi=3.14;return;}
if(!im)
{*farg=re;*ffi=0;return;}
*farg=pow(re*re+im*im,0.5);
*ffi=atan(im/re);
}
main()
{yyparse();}

23) Разработать транслятор для преобразования алгебраического формата записи комплексных чисел в эквивалентную тригонометрическую форму. Входные записи любых
комплексных чисел должны передаваться транслятору строками потока стандартного ввода, а результаты трансляции должны отображать строки потока стандартного вывода. При
этом любые численные значения во входных и выходных записях комплексных чисел должны быть заданы обыкновенными дробями, где числитель и знаменатель разделены
символом '/'.

LEX:

%{
#include<stdio.h>
#include"y.tab.h"
#define YYSTYPE
extern YYSTYPE yylval;
%}
%Start NOM IM
%%
^[-]?([0]|[1-9][0-9]*)/\/ {yylval=atoi(yytext);
BEGIN NOM;return RENM;}
<IM>[+-]([0]|[1-9][0-9]*)/\/ {yylval=atoi(yytext);
BEGIN NOM;return IMNM;}
<NOM>[0] {return ZERO;}
\/ {return '/';}
<NOM>[1-9][0-9]*/(j\n) {yylval=atoi(yytext);return IMDNM;}
<NOM>[1-9][0-9]*/[+-] {BEGIN IM; yylval=atoi(yytext);return REDNM;}
\n |
. {return 0;}

YACC:

%{
#include <stdio.h>
#include <math.h>
#include<ctype.h>
#define ST 1000
void drob(double,int*,int*);
void trans(double ,double ,double *, double *);
double arg, fi, im1,re1;
int fn,fd,an,ad;
%}
%token RENM IMNM REDNM IMDNM ZERO
%%
complex: real image
{trans(re1,im1,&arg,&fi);
drob(arg,&an,&ad);
drob(fi,&fn,&fd);
printf("%d/%d*(cos(%d/%d)+j*sin(%d/%d))\n",
an,ad,fn,fd,fn,fd);}
real: RENM '/' REDNM {re1=(double)$1/$3;}
| RENM '/' ZERO {
puts("ZERO FAKE");return 0;}
image: IMNM '/'IMDNM {im1=(double)$1/$3;}
| IMNM '/' ZERO {
puts("ZERO FAKE");return 0;}
%%
int yyerror(char*s)
{puts(s);}
void drob(double num,int *fnm,int *fdnm)
{
int a,b,p;
*fnm=(int)(num*ST);
*fdnm=ST;
for(a=abs(*fnm),b=abs(*fdnm);a*b;)
{ if(a>=b) a=a%b;
else b=b%a;
}
p=a+b;
*fnm/=p;
*fdnm/=p;
}
void trans(double re,double im,
double *farg, double *ffi)
{
if(!re)
{*farg=im;*ffi=3.14;return;}
if(!im)
{*farg=re;*ffi=0;return;}
*farg=pow(re*re+im*im,0.5);
*ffi=atan(im/re);
}
main()
{yyparse();}

24)
Разработать транслятор для преобразования записи любой периодической десятичной дроби в обыкновенную дробь. Записи периодических десятичных дробей должны
передаваться транслятору строками стандартного ввода в формате вещественных чисел с фиксированной точкой, где период указан в круглых скобках.
Результаты трансляции должны отображаться строками стандартного вывода, где числители и знаменатели обыкновенных дробей разделены символом '/'.
LEX:
%{
#include "y.tab.h"
%}
%%
(([0-9]*[a-zA-z]+[0-9]*)+)/[.()] {return ER;}

(([1-9][0-9]*)|[0])/[.] {yylval=atoi(yytext); return NUMB;}


([0-9]+)/[(] {yylval=atoi(yytext); return PART;}
([1-9][0-9]*)/[)] {yylval=atoi(yytext); return PERIOD;}
.|
\n
%%

YACC:
%{
#include <stdio.h>
%}
%token NUMB PART PERIOD ER ER2
%start list
%%
list:
|list drob sep
|list error sep {yyerrok;}
;
drob: NUMB PART PERIOD { trans1($1,$2,$3); return 0;}
| NUMB PERIOD { trans2($1,$2); return 0;}
| NUMB ER PERIOD {yyerror("wrong input");return 0;}
| ER PERIOD {yyerror("wrong input");return 0;}
| ER PART PERIOD {yyerror("wrong input");return 0;}
| ER ER {yyerror("wrong input");return 0;}
;
sep:
|' '
|'\n'
|'\t'
;
%%

int yyerror(const char *str)


{
fprintf(stderr, "error: %s\n", str);
}
int yywrap()
{
return 1;
}
int trans2(int a, int b)
{
int d=0, c=0, nod=0;
c=b;
while(c>0)
{c=c/10;
d=d*10+9;}
nod=NOD(b,d);
d=d/nod;
b=b/nod;
b=a*d+b;
printf("Here comes the Magic: %d/%d\n",b,d);
}
int trans1(int a, int b, int c)
{
int d=0,e=0, nod=0, i=0;
e=c;
while(e>0)
{e=e/10;
d=d*10+9;
i++;}
e=b;
while(e>0)
{e=e/10;
d=d*10;
}
e=b;
while(i>0)
{e=e*10;
i--;}
c=e+c;
c=c-b;
nod=NOD(c,d);
d=d/nod;
c=c/nod;
c=a*d+c;
printf("Here comes the Magic: %d/%d\n",c,d);
}
int NOD(int a,int b)
{
while(a!=0 && b!=0)
{
if(a>=b) a=a%b;
else b=b%a;
}
return a+b;
}
int main()
{
yyparse();
}

25)Разработать транслятор для преобразования записи любого вещественного числа, которое задано в экспоненциальной форме, в формат обыкновенной дроби. Входные записи
вещественных чисел должны передаваться транслятору строками стандартного ввода. Результаты трансляции должны отображаться строками стандартного вывода. При этом все
записи вещественных чисел должны соответствовать формату констант системы программирования С а числитель и знаменатель обыкновенной дроби разделены /.
LEX:
DOT "."
%{
#include"y.tab.h"
%}
%%
^[+]/{DOT} {yylval=strdup(yytext); return SGN;}
^[-]([1-9][0-9]*)/{DOT} {yylval=strdup(yytext); return CEL;}
^[+]?(([1-9][0-9]*)|[0])/{DOT} {yylval=strdup(yytext); return CEL;}
^[-]/{DOT} {yylval=strdup(yytext); return SGNM;}
^[-][0]/{DOT} {yylval=strdup(yytext); return CELM;}
\.([0-9]*)/[eE] {yylval=strdup(yytext+1); return DRB;}
[eE][-+][0-9]{1,2}$ {yylval=strdup(yytext+1); return STP;}
([a-zA-z ]*[0-9]*)* {return ER;}
\n |
. ;

YACC:
%{
#include <stdio.h>
#include <string.h>
#define YYSTYPE char *
int a=0, b=0, c=0, stp=0;
int trans(int a, int b, int c, int stp);
int transM(int a, int b, int c, int stp);
%}
%start list
%token CEL DRB SGN CELM SGNM STP ER
%%
list:
|list drob
;
drob: CEL DRB STP
{a=strlen($2); b=atoi($1); c=atoi($2);
stp=atoi($3); trans(a,b,c,stp); return 0;}
|CELM DRB STP
{a=strlen($2); b=0; c=atoi($2);
stp=atoi($3); transM(a,b,c,stp); return 0;}
|SGN DRB STP
{a=strlen($2); b=atoi($1); c=atoi($2);
stp=atoi($3); trans(a,b,c,stp); return 0;}
|SGNM DRB STP
{a=strlen($2); b=0; c=atoi($2); stp=atoi($3);
transM(a,b,c,stp); return 0;}
|DRB STP
{a=strlen($1); b=0; c=atoi($1); stp=atoi($2);
trans(a,b,c,stp); return 0;}
;
%%
int yyerror()
{puts("ERROR");}
int yywrap()
{return 0;}
int trans(int a, int b, int c, int stp)
{
int i=0, k=1, f=0;
double drb=0.0, sp=1.0;
for(i=0;i<a;i++)
{k=k*10;}
if(b<0)
{b=b*-1;drb=b+(double)c/k;f=1;}
else{drb=b+(double)c/k;}
if(stp>0)
{for(i=0;i<stp;i++)
{sp=sp*10;}}
else
{stp=stp*-1;
for(i=0;i<stp;i++)
{sp=sp/10;}}
if(f)
{drb=drb*sp*-1;}
else
{drb=drb*sp;}
if(k/sp<1)
{printf ("Result = %.0f/%.0f\n",
drb*sp/k, sp/k);}
else
{printf ("Result = %.0f/%.0f\n",
drb*k/sp, k/sp);}
}
int transM(int a, int b,
int c, int stp)
{
int i=0, k=1;
double drb=0.0, sp=1.0;
for(i=0;i<a;i++)
{k=k*10;}

drb=b+(double)c/k;
if(stp>0)
{for(i=0;i<stp;i++)
{sp=sp*10;}}
else
{stp=stp*-1;
for(i=0;i<stp;i++)
{sp=sp/10;}}
drb=drb*sp*-1;
if(k/sp<1)
{printf ("Result = %.0f/%.0f\n",
drb*sp/k, sp/k);}
else
{printf ("Result = %.0f/%.0f\n",
drb*k/sp, k/sp);}
}
main()
{yyparse();}

26)
Разработать синтаксический анализатор для грамматического вывода бинарных векторов, которые соответствуют КС-языку L={0n 1n| n>1}.
YACC:
%{
#include <stdio.h>
%}
%token ZERO ONE NEWLINE
%%
complex:
| ono NEWLINE {puts("good");return 0;}

ono: ZERO ono ONE


| ZERO ONE
;
%%
int yylex()
{char c;
c=getchar();
{
if(c=='0')return ZERO;
if(c=='1')return ONE;
if(c=='\n')return NEWLINE;
}
}
int yyerror(char*s)
{puts(s);}
int main()
{return(yyparse());
}

27)

LEX:
%{
#include <stdio.h>
int yywrap(void){
return 1;
}
%}
%start AA BB CC DD EE FF GG HH II JJ KK LL MM NN OO PP

%%
^0 BEGIN AA;
^1 BEGIN BB;
^2 BEGIN CC;
^3 BEGIN DD;
^4 BEGIN EE;
^5 BEGIN FF;
^6 BEGIN GG;
^7 BEGIN HH;
^8 BEGIN II;
^9 BEGIN JJ;
<AA>0 ;
<AA>[ \t\n] {printf("Right!\n"); BEGIN 0;}
<BB>0 BEGIN AA;
<BB>1 ;
<BB>[ \t\n] {printf("Right!\n"); BEGIN 0;}
<CC>0 BEGIN AA;
<CC>1 BEGIN BB;
<CC>2 ;
<CC>[ \t\n] {printf("Right!\n"); BEGIN 0;}
<DD>0 BEGIN AA;
<DD>1 BEGIN BB;
<DD>2 BEGIN CC;
<DD>3 ;
<DD>[ \t\n] {printf("Right!\n"); BEGIN 0;}
<EE>0 BEGIN AA;
<EE>1 BEGIN BB;
<EE>2 BEGIN CC;
<EE>3 BEGIN DD;
<EE>4 ;
<EE>[ \t\n] {printf("Right!\n"); BEGIN 0;}
<FF>0 BEGIN AA;
<FF>1 BEGIN BB;
<FF>2 BEGIN CC;
<FF>3 BEGIN DD;
<FF>4 BEGIN EE;
<FF>5 ;
<FF>[ \t\n] {printf("Right!\n"); BEGIN 0;}
<GG>0 BEGIN AA;
<GG>1 BEGIN BB;
<GG>2 BEGIN CC;
<GG>3 BEGIN DD;
<GG>4 BEGIN EE;
<GG>5 BEGIN FF;
<GG>6 ;
<GG>[ \t\n] {printf("Right!\n"); BEGIN 0;}
<HH>0 BEGIN AA;
<HH>1 BEGIN BB;
<HH>2 BEGIN CC;
<HH>3 BEGIN DD;
<HH>4 BEGIN EE;
<HH>5 BEGIN FF;
<HH>6 BEGIN GG;
<HH>7 ;
<HH>[ \t\n] {printf("Right!\n"); BEGIN 0;}
<II>0 BEGIN AA;
<II>1 BEGIN BB;
<II>2 BEGIN CC;
<II>3 BEGIN DD;
<II>4 BEGIN EE;
<II>5 BEGIN FF;
<II>6 BEGIN GG;
<II>7 BEGIN HH;
<II>8 ;
<II>[ \t\n] {printf("Right!\n"); BEGIN 0;}
<JJ>0 BEGIN AA;
<JJ>1 BEGIN BB;
<JJ>2 BEGIN CC;
<JJ>3 BEGIN DD;
<JJ>4 BEGIN EE;
<JJ>5 BEGIN FF;
<JJ>6 BEGIN GG;
<JJ>7 BEGIN HH;
<JJ>8 BEGIN II;
<JJ>9 ;
<JJ>[ \t\n] {printf("Right!\n"); BEGIN 0;}
. BEGIN 0;
\n {printf("Wrong!\n"); BEGIN 0;}
%%

int main(){
yylex();
}

28)
Разработать транслятор для преобразования записи любой обыкновенной дроби с необязательным знаком в конечную десятичную дробь. Записи обыкновенных дробей, в
которых числитель и знаменатель разделены символом '/', должны передаваться транслятору строками потока стандартного ввода. Результаты трансляции должны отображаться
через поток стандартного вывода строками вещественных чисел в экспоненциальной форме.

LEX:
%{
#include"y.tab.h"
%}
LINE "/"
%%
^[+-]?(([1-9][0-9]*)|(0))/{LINE} {yylval=atoi(yytext); return NUM;}
\/[+-]?[0]$ {yylval=atoi(yytext+1); return DEN1;}
\/[+-]?([1-9][0-9]*)$ {yylval=atoi(yytext+1); return DEN;}
([a-zA-z ]*[0-9]*)* {return ER;}
\n | . ;
YACC:
%{
#include <stdio.h>
%}
%start list
%token NUM DEN DEN1 ER
%%
list:
|list drob
;
drob: NUM DEN {printf("Result = %.3E\n",(double)$1/$2); return 0;}
|NUM DEN1 {puts("ZERO FAKE"); return 0;}
|NUM ER {puts("ERROR"); return 0;}
;
%%
int yyerror()
{puts("ERROR");}
int yywrap()
{return 0;}
main()
{yyparse();}

29)

YACC:
%{
#include <stdio.h>
%}
%start list
%%
list:
| list '\n'
| list vector '\n'{printf("Right vector \n");}
| list error '\n'
{yyerrok;}
;
vector: one zero
;
one: '1'
| one '1'
;
zero: '0'
| zero '0'
;
%%
yylex(){
int c;
while((c=getchar())==' ') ; /*пропуск пробелов*/
return(c);
}
yyerror(s)
{ fprintf(stderr, "wrong vector or error in input data \n");}
main() {return(yyparse());}

30)
Разработать транслятор для преобразования записи любого вещественного числа, которое задано в экспоненциальной форме, в формат с фиксированной точкой. Входные записи
вещественных чисел должны передаваться транслятору строками стандартного ввода. Результаты трансляции должны отображаться строками стандартного вывода. При этом все
записи вещественных чисел должны соответствовать формату констант системы программирования С.
LEX:
DOT "."
%{
#include"y.tab.h"
%}
%%
^[+]/{DOT} {yylval=strdup(yytext); return SGN;}
^[-]([1-9][0-9]*)/{DOT} {yylval=strdup(yytext); return CEL;}
^[+]?(([1-9][0-9]*)|[0])/{DOT} {yylval=strdup(yytext); return CEL;}
^[-]/{DOT} {yylval=strdup(yytext); return SGNM;}
^[-][0]/{DOT} {yylval=strdup(yytext); return CELM;}
\.([0-9]*)/[eE] {yylval=strdup(yytext+1); return DRB;}
[eE][-+][0-9]{1,2}$ {yylval=strdup(yytext+1); return STP;}
([a-zA-z ]*[0-9]*)* {return ER;}
\n |
. ;

YACC:
%{
#include <stdio.h>
#include <string.h>
#define YYSTYPE char *
int a=0, b=0, c=0, stp=0;
int trans(int a, int b, int c, int stp);
int transM(int a, int b, int c, int stp);
%}
%start list
%token CEL DRB SGN CELM SGNM STP ER
%%
list:
|list drob
;
drob: CEL DRB STP {a=strlen($2); b=atoi($1); c=atoi($2); stp=atoi($3); trans(a,b,c,stp); return 0;}
|CELM DRB STP {a=strlen($2); b=0; c=atoi($2); stp=atoi($3); transM(a,b,c,stp); return 0;}
|SGN DRB STP {a=strlen($2); b=atoi($1); c=atoi($2); stp=atoi($3); trans(a,b,c,stp); return 0;}
|SGNM DRB STP {a=strlen($2); b=0; c=atoi($2); stp=atoi($3); transM(a,b,c,stp); return 0;}
|DRB STP {a=strlen($1); b=0; c=atoi($1); stp=atoi($2); trans(a,b,c,stp); return 0;}
;
%%
int yyerror() {puts("ERROR");}
int yywrap() {return 0;}
int trans(int a, int b, int c, int stp) {
int i=0, k=1, f=0;
double drb=0.0, sp=1.0;
for(i=0;i<a;i++)
{k=k*10;}
if(b<0)
{b=b*-1;drb=b+(double)c/k;f=1;}
else{drb=b+(double)c/k;}
if(stp>0)
{for(i=0;i<stp;i++)
{sp=sp*10;}}
else
{stp=stp*-1;
for(i=0;i<stp;i++)
{sp=sp/10;}}
if(f) {drb=drb*sp*-1;}
else {drb=drb*sp;}
printf ("Result = %.5f\n",drb);
}
int transM(int a, int b, int c, int stp) {
int i=0, k=1;
double drb=0.0, sp=1.0;
for(i=0;i<a;i++)
{k=k*10;}
drb=b+(double)c/k;
if(stp>0)
{for(i=0;i<stp;i++)
{sp=sp*10;}}
else {stp=stp*-1;
for(i=0;i<stp;i++)
{sp=sp/10;}}
drb=drb*sp*-1;
printf ("Result = %.5f\n",drb);}
main() {yyparse();}

Вам также может понравиться