Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
melkie_progi.docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
53.45 Кб
Скачать

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;}

;

%%

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]