0% found this document useful (0 votes)
8 views10 pages

SplitPDFFile 1 To 10

kkkkkkkkkkkkkkkk

Uploaded by

kabilanmaran2004
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
8 views10 pages

SplitPDFFile 1 To 10

kkkkkkkkkkkkkkkk

Uploaded by

kabilanmaran2004
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 10

Ex6

Int yywrap() { return 1; }

ChatGPT said: Type.y


ChatGPT %{
To simplify the program without altering its output, we can remove redundancy, #include <stdio.h>
streamline the logic, and refactor the code for clarity. Here's the shortened and cleaned-
#include <string.h>
up version:
Char variable[20][2][20];
Int count = 0;
Type.l
Void checktype(char result[], char op[], char arg1[], char arg2[], char returnval[]);
%{
%}
#include “y.tab.h”
#include <stdio.h>
%union {
#include <string.h>
Char *var;
Int LineNo = 1;
}
%}

%token <var> NUM VAR


Identifier [a-zA-Z][_a-zA-Z0-9]*
%token MAIN
Number [0-9]+|([0-9]*\.[0-9]+)
%token <var> TYPE
%type <var> EXPR
%%

Main\(\) return MAIN;


%left ‘+’ ‘-‘
Int|char|float { yylval.var = strdup(yytext); return TYPE; }
%left ‘*’ ‘/’
{identifier} { yylval.var = strdup(yytext); return VAR; }

{number} { yylval.var = strdup(yytext); return NUM; }


%%
[ \t]+ ; // Ignore spaces and tabs
PROGRAM : MAIN BLOCK ;
\n LineNo++;
. return yytext[0];
BLOCK : ‘{‘ CODE ‘}’ ;
%%
Printf(“\nFile not found\n”);
CODE : CODE STATEMENT | STATEMENT ; Return 1;

}
STATEMENT : DESCT ‘;’ Yyin = fp;
| ASSIGNMENT ‘;’ ; }
Return yyparse();

DESCT : TYPE VAR { }


Strcpy(variable[count][0], $1);
Strcpy(variable[count][1], $2); Void checktype(char result[], char op[], char arg1[], char arg2[], char returnval[]) {

Count++; Char type1[20] = “”, type2[20] = “”, resulttype[20] = “”;


Printf(“%s\t%s\n”, $1, $2);
}; For (int I = 0; I < count; i++) {
If (!strcmp(variable[i][1], arg1)) strcpy(type1, variable[i][0]);

ASSIGNMENT: EXPR ‘=’ EXPR { checktype($1, “=”, $3, “”, $1); } ; If (!strcmp(variable[i][1], arg2)) strcpy(type2, variable[i][0]);

If (!strcmp(variable[i][1], result)) strcpy(resulttype, variable[i][0]);


EXPR : EXPR ‘+’ EXPR { checktype($$, “+”, $1, $3, $$); } }

| EXPR ‘-‘ EXPR { checktype($$, “-“, $1, $3, $$); }


| EXPR ‘*’ EXPR { checktype($$, “*”, $1, $3, $$); } If (!strcmp(type1, type2) && !strcmp(resulttype, type2))
| EXPR ‘/’ EXPR { checktype($$, “/”, $1, $3, $$); } Printf(“\n%s = %s %s %s\t=> Compatible”, result, arg1, op, arg2);
| VAR Else

| NUM ; Printf(“\n%s = %s %s %s\t=> Incompatible”, result, arg1, op, arg2);


%%
Strcpy(returnval, “”);
Int main(int argc, char *argv[]) { }
If (argc > 1) {

FILE *fp = fopen(argv[1], “r”); Int yyerror() {

If (!fp) { Printf(“\nError\n”);
Return 0; Changes Made:
} Removed redundant code, such as VARLIST, which is unused.

Input File (inp.c) Simplified checktype and removed unnecessary parameters.


Main() { Consolidated space/tab and newline handling in the lexer.
Int a; Improved readability and eliminated unnecessary variables.
Int b; This retains the functionality while making the code more concise.

Int r;
Float e; Ex5
Float f;

R = a + b; Threeaddrcode.l
F = r + e; C
E = f + e; Copy code
} %{

Output Commands #include “y.tab.h”

$ yacc -d type.y #include <stdio.h>


$ lex type.l #include <string.h>

$ cc y.tab.c lex.yy.c -o typechecker Int LineNo = 1;


$ ./typechecker inp.c %}
Output
Int a Identifier [a-zA-Z][_a-zA-Z0-9]*

Int b Number [0-9]+|([0-9]*\.[0-9]+)


Int r
Float e %%
Float f Main\(\) return MAIN;
R = a + b => Compatible If return IF;

F = r + e => Incompatible Else return ELSE;

E = f + e => Compatible While return WHILE;


Int|char|float return TYPE; Void push(int data) { stk.items[++stk.top] = data; }
{identifier} { yylval.var = strdup(yytext); return VAR; } Int pop() { return stk.items[stk.top--]; }

{number} { yylval.var = strdup(yytext); return NUM; }


\<|\>|\>=|\<=|== { yylval.var = strdup(yytext); return RELOP; } Void addQuadruple(char *op, char *arg1, char *arg2, char *result) {
[ \t]+ ; // Ignore spaces and tabs Sprintf(QUAD[Index].op, “%s”, op);
\n LineNo++; Sprintf(QUAD[Index].arg1, “%s”, arg1);

. return yytext[0]; Sprintf(QUAD[Index].arg2, “%s”, arg2);


%% Sprintf(QUAD[Index].result, “t%d”, tIndex++);
Sprintf(result, “%s”, QUAD[Index++].result);

Int yywrap() { return 1; } }


Threeaddrcode.y %}
C
Copy code %union { char var[10]; }

%{ %token <var> NUM VAR RELOP MAIN IF ELSE WHILE TYPE

#include <string.h> %type <var> EXPR ASSIGNMENT CONDITION IFST ELSEST WHILEST
#include <stdio.h>

Struct quad { %left ‘+’ ‘-‘


Char op[5], arg1[10], arg2[10], result[10]; %left ‘*’ ‘/’
} QUAD[30];
Int Index = 0, tIndex = 0, StNo; %%

PROGRAM : MAIN BLOCK ;


Struct stack {
Int items[100], top; BLOCK : ‘{‘ CODE ‘}’ ;
} stk = { .top = -1 };
CODE : STATEMENT CODE | STATEMENT ;

Extern int LineNo;

STATEMENT : DESCT ‘;’


| ASSIGNMENT ‘;’ Int trueIndex = pop();
| IFST ELSEST? QUAD[trueIndex].result[0] = Index + ‘0’;

| WHILEST ; };

DESCT : TYPE VARLIST ; CONDITION : VAR RELOP VAR {


addQuadruple($2, $1, $3, $$);

VARLIST : VAR ‘,’ VARLIST | VAR ; StNo = Index – 1;


};
ASSIGNMENT: VAR ‘=’ EXPR {

Sprintf(QUAD[Index].op, “=”); WHILEST : WHILE ‘(‘ CONDITION ‘)’ BLOCK {


Sprintf(QUAD[Index].arg1, “%s”, $3); QUAD[Index++] = (struct quad){“GOTO”, “”, “”, “-1”};
Sprintf(QUAD[Index].arg2, “”); QUAD[StNo].result[0] = Index + ‘0’;
Sprintf(QUAD[Index++].result, “%s”, $1); };

};

%%
EXPR : EXPR ‘+’ EXPR { addQuadruple(“+”, $1, $3, $$); } Int main(int argc, char *argv[]) {

| EXPR ‘-‘ EXPR { addQuadruple(“-“, $1, $3, $$); } If (argc > 1) {


| EXPR ‘*’ EXPR { addQuadruple(“*”, $1, $3, $$); } FILE *fp = fopen(argv[1], “r”);
| EXPR ‘/’ EXPR { addQuadruple(“/”, $1, $3, $$); } If (!fp) { printf(“\nFile not found\n”); return 1; }
| VAR | NUM ; Yyin = fp;

}
IFST : IF ‘(‘ CONDITION ‘)’ BLOCK { Yyparse();
QUAD[Index++] = (struct quad){“GOTO”, “”, “”, “-1”}; Printf(“\n\n------------------------------\nPos Operator Arg1 Arg2 Result\n”);
Push(Index – 1); For (int I = 0; I < Index; i++)
}; Printf(“%d\t%s\t%s\t%s\t%s\n”, I, QUAD[i].op, QUAD[i].arg1, QUAD[i].arg2,
QUAD[i].result);

Printf(“------------------------------\n”);
ELSEST : ELSE BLOCK {
Return 0; 0 < a b t0
} 1 == t0 FALSE 5

2 + a b t1
Int yyerror() { 3 = t1 a
Printf(“\nError on line no: %d”, LineNo); 4 GOTO 5
Return 0; 5 < a b t2

} 6 == t2 FALSE 10
Test.c 7 + a b t3
C 8 = t3 a

Copy code 9 GOTO 5


Main() { 10 <= a b t4
Int a, b, c; 11 == t4 FALSE 15
If (a < b) { a = a + b; } 12 - a b t5

While (a < b) { a = a + b; } 13 = t5 c

If (a <= b) { c = a – b; } else { c = a + b; } 14 GOTO 17


} 15 + a b t6

Commands to Execute 16 = t6 c
Bash Simplifications Made:
Copy code Consolidated repetitive code and logic.
$ yacc -d threeaddrcode.y Removed unnecessary sprintf in favor of direct string assignments.
$ lex threeaddrcode.l Combined similar actions like GOTO handling.
$ gcc lex.yy.c y.tab.c -o threeaddr Simplified stack operations by directly working with indexes.
$ ./threeaddr test.c This shortened version achieves the same output with better clarity and reduced
redundancy.
Output
Css

Copy code

Pos Operator Arg1 Arg2 Result


Ex4c Expr:

Cal.y ‘(‘ expr ‘)’ { $$ = $2; }


C | expr ‘*’ expr { $$ = $1 * $3; }
Copy code | expr ‘/’ expr { $$ = $1 / $3; }
%{ | expr ‘%’ expr { $$ = $1 % $3; }

#include <stdio.h> | expr ‘+’ expr { $$ = $1 + $3; }


Int regs[26]; // Register array for storing variables | expr ‘-‘ expr { $$ = $1 - $3; }
%} | expr ‘&’ expr { $$ = $1 & $3; }

| expr ‘|’ expr { $$ = $1 | $3; }


%start list | ‘-‘ expr %prec UMINUS { $$ = -$2; }
%token DIGIT LETTER | LETTER { $$ = regs[$1]; }
%left ‘|’ ‘&’ | number

%left ‘+’ ‘-‘ ;

%left ‘*’ ‘/’ ‘%’


%left UMINUS Number:

DIGIT { $$ = $1; }
%% | number DIGIT { $$ = 10 * $1 + $2; }
List: ;
| list stat ‘\n’

| list error ‘\n’ { yyerror(“Invalid Expression”); } %%


; Int main() { return yyparse(); }

Stat: Void yyerror(char *s) { fprintf(stderr, “%s\n”, s); }


Expr { printf(“%d\n”, $1); }

| LETTER ‘=’ expr { regs[$1] = $3; } Int yywrap() { return 1; }

; Cal.l
C (9*3)/3
Copy code A=9

%{ B=4
#include “y.tab.h” A+b
%} Output:

%% Plaintext
[a-z] { yylval = yytext[0] – ‘a’; return LETTER; } Copy code
[0-9] { yylval = yytext[0] – ‘0’; return DIGIT; } 17

[ \t]+ ; // Ignore spaces and tabs 9


. { return yytext[0]; } 13
%% Changes and Optimizations:
Simplified Variable Declarations: Removed unnecessary base variable in cal.y for base-
8 or base-10 evaluation as the functionality isn’t used.
Int yywrap() { return 1; }
Simplified Lexer: Removed explicit handling of non-alphanumeric characters like [^a-z0-
Commands to Execute
9\b] since . in the lexer rule covers all other cases.
Bash
Reduced Repetition: Combined similar cases in rules for compactness without affecting
Copy code functionality.
$ yacc -d cal.y Improved Error Handling: Added a meaningful error message for invalid expressions.
$ lex cal.l This compact version is easier to understand and maintain while providing the same
functionality and output.
$ gcc y.tab.c lex.yy.c -o calc
Ex1b
$ ./calc
Optimized Code
Sample Input and Output
C
Input:
Copy code
#include <stdio.h>
Plaintext
#include <ctype.h>
Copy code
#include <string.h>
9+8
If (isOperator(ch)) {
Void keyw(char *p); Printf(“%c is an operator\n”, ch);

Int I = 0, id = 0, kw = 0, num = 0, op = 0; Op++;


Str[i] = ‘\0’;
Char keys[35][10] = {“main”, “auto”, “break”, “case”, “char”, “const”, “continue”, Keyw(str);
“default”, “do”, “double”, “else”, “enum”, “extern”, “float”, } else if (isSeparator(ch)) {

“for”, “goto”, “if”, “int”, “long”, “register”, “return”, If (ch == ‘#’) {


“short”, “signed”, “sizeof”, “static”, “struct”, “switch”, While ((ch = fgetc(f1)) != ‘>’)
“typedef”, “union”, “unsigned”, “void”, “volatile”, “while”}; Printf(“%c”, ch);

Printf(“%c is a header file\n”, ch);


Int isOperator(char ch) { }
Return strchr(“!%^&*-+=~|.<>/?”, ch) != NULL; Str[i] = ‘\0’;
} Keyw(str);

} else {

Int isSeparator(char ch) { Str[i++] = ch;


Return strchr(“ \t\n,;(){}[]#\”<>”, ch) != NULL; }

} }

Int main() { Printf(“Keywords: %d\nIdentifiers: %d\nOperators: %d\nNumbers: %d\n”, kw, id, op,
num);
Char ch, str[25];
Fclose(f1);
FILE *f1 = fopen(“input1.c”, “r”);
Return 0;
If (!f1) {
}
Printf(“Error opening file.\n”);
Return 1;
Void keyw(char *p) {
}
If (p[0] == ‘\0’) return;

If (isdigit(p[0])) {
While ((ch = fgetc(f1)) != EOF) {
Printf(“%s is a number\n”, p); Copy code
Num++; $ gcc lexnew.c -o lexnew

} else { $ ./lexnew
For (int k = 0; k < 32; k++) { For the same input, the output remains identical:
If (strcmp(keys[k], p) == 0) {
Printf(“%s is a keyword\n”, p); Plaintext

Kw++; Copy code


I = 0; Simple is an identifier
Return; Program is an identifier

} #include<stdio.h> is a header file


} Void is a keyword
Printf(“%s is an identifier\n”, p); Main is a keyword
Id++; Int is a keyword

} I is an identifier

I = 0; Const is a keyword
} = is an operator

Explanation of Changes: A is an identifier


Separated Logic for Operators and Separators: Introduced helper functions isOperator Float is a keyword
and isSeparator for cleaner condition checks.
= is an operator
Removed Redundant Loops: Simplified loop logic to avoid duplicate checks.
J is an identifier
Compact Header File Processing: Condensed # and > header file handling into a single
. is an operator
block.
10 is a number
Streamlined keyw Function: Merged keyword and identifier checks into a cleaner loop.
50 is a number
Removed /* */ Handling: It was incomplete and not relevant to the input example.
Keywords: 5
Usage and Output:
Identifiers: 5
Save the program as lexnew.c, compile and run it as follows:
Operators: 3

Numbers: 3
Bash

You might also like