Compiler Record

You might also like

Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 50

Exp No: 01

Date: COUNT THE NUMBER OF CHARACTERS, WORDS AND SENTENCES IN A FILE

AIM:

To write a program that counts the number of characters, words and sentences in a file.

PROCEDURE:

1. Prompt the user to enter the source file name.


2. Open the file for reading.
3. Check if the file was opened successfully; if not, display an error message and exit.
4. Read the file character by character and count the number of characters, words (based on spaces),
and lines (based on newline characters).
5. Close the file.
6. Output the total number of characters, words, and lines

PROGRAM CODE:

#include<iostream>
#include<fstream>
#include<string.h>
#include<cstdlib>
using namespace std;
int main()
{
int c=0,w=0,l=0;
FILE *fr;
char fname[20],ch;
cout<<"\n Enter Source File Name : ";
gets(fname);
fr=fopen(fname,"r");
if(fr==NULL)
{
cout<<"\n Invalid File Name. \n No such File or Directory ";
exit(0);
}
ch=fgetc(fr);
while(ch!=EOF)
{
if(ch!=' ' && ch!='\n')
c++;
if(ch==' ')
w++;
if(ch=='\n')
{
l++;
w++;
}
ch=fgetc(fr);
}
fclose(fr);
cout<<" -------------------------------------";
cout<<"\n Total No. of Characters : "<<c;
cout<<"\n Total No. of Words : "<<w;
cout<<"\n Total No. of Lines : "<<l;
return 0;
}
SAMPLE INPUT:

SAMPLE OUTPUT:

RESULT:

Thus, the above code to count the number of words, lines and characters in a file is executed successfully.
Exp No: 02
Date: COUNT THE NUMBER OF VOWELS AND CONSONANTS IN A FILE

AIM:

To write a program that counts the number of vowels and consonants in a file.

PROCEDURE:

1. Prompt the user to enter the source file name.


2. Open the file for reading.
3. Initialize counters for vowels and consonants.
4. Print the content of the file.
5. Iterate through each character in the file content.
6. Check if the character is a vowel (both lowercase and uppercase); if it is, increment the vowel
count.
7. Check if the character is an alphabet letter using isalpha(); if it is, increment the consonant count.
8. Print the counts of vowels and consonants.

PROGRAM CODE:

# Open the file in read mode

with open("sample.txt", 'r') as file:

content = file.read()

vowel = 0

consonants = 0

print(content)

for line in content:

if line in "aeiouAEIOU":

vowel += 1

elif line.isalpha():

consonants += 1

print(f"Vowels: {vowel}")

print(f"Consonants: {consonants}")
SAMPLE INPUT:

SAMPLE OUTPUT:

RESULT:

Thus, the above code to count the number of vowels and consonants in a file is executed successfully.
Exp No: 03
Date: PERFORM STRING OPERATIONS

AIM:

To perform ten string operations without using Built-In functions in Python.

PROCEDURE:

1. Largest String Comparison:


 Compare the lengths of strings x and y using a loop to count characters,and output the
string with the larger count.
2. String Slicing:
 Accept an integer input i.
 Use string slicing to extract the substring of x from the beginning up to index i.
 Print the sliced substring.
3. String Reversal:
 Utilize string slicing with a step of -1 to reverse both strings x and y.
 Print the reversed strings.
4. Concatenation:
 Concatenate the contents of strings x and y using the + operator.
 Print the concatenated result.
5. String Length:
 Traverse each character in strings x and y using loops, incrementing a counter for each
character.
 Print the counters as the lengths of the respective strings.
6. Greeting:
 Accept a string input for the name.
 Use string concatenation to create a greeting message containing the provided name.
 Print the greeting message.
7. Palindrome Check:
 Compare strings x and y to their reversed versions using a simple equality check.
 If they are equal, print "Palindrome"; otherwise, print "Not a Palindrome".

8. Count Vowels:
 Define a list of vowel characters.
 Iterate through each character in strings x and y.
 If a character is present in the vowel list, increment the respective vowel counter.
 Print the counts of vowels.
9. Vowel Presence Check:
 Define a list of vowel characters.
 Iterate through each character in strings x and y.
 If a character matches a vowel, print "Vowels is present" for the corresponding string.

10. Count Consonants:


 Define a list of vowel characters.
 Iterate through each character in strings x and y.
 If a character is not present in the vowel list, increment the respective consonant counter.
 Print the counts of consonants.

PROGRAM CODE:

# 1. Concatenation

str1 = "Hello"

str2 = "World"

result = ""

for char in str1:

result += char

for char in str2:

result += char

print("Concatenation:", result)

# 2. Length Calculation

length = 0

for char in str1:

length += 1

print("Length:", length)

# 3. Substring

substring = ""

for i in range(2, 5):

substring += str1[i]

print("Substring:", substring)

# 4. String Copy

copy = ""

for char in str1:

copy += char

print("Copy:", copy)
# 5. Reverse String

reverse = ""

for i in range(len(str1) - 1, -1, -1):

reverse += str1[i]

print("Reverse:", reverse)

# 6. String Comparison

str3 = "Hello"

is_equal = True

for i in range(len(str1)):

if str1[i] != str3[i]:

is_equal = False

break

print("String Comparison:", is_equal)

# 7. Uppercase Conversion

uppercase = ""

for char in str1:

if 'a' <= char <= 'z':

uppercase += chr(ord(char) - ord('a') + ord('A'))

else:

uppercase += char

print("Uppercase Conversion:", uppercase)

# 8. Lowercase Conversion

lowercase = ""

for char in str1:

if 'A' <= char <= 'Z':

lowercase += chr(ord(char) - ord('A') + ord('a'))

else:
lowercase += char

print("Lowercase Conversion:", lowercase)

# 9. Counting Occurrences of a Character

count = 0

for char in str1:

if char == 'l':

count += 1

print("Count of 'l':", count)

# 10. Palindrome Check

is_palindrome = True

for i in range(len(str1) // 2):

if str1[i] != str1[len(str1) - 1 - i]:

is_palindrome = False

break

print("Palindrome Check:", is_palindrome)


OUTPUT:

RESULT:

Thus, we have successfully executed the ten string operations without using Built-In functions in Python.
Exp No: 04
Date: TOKEN SEPARATION USING HIGH LEVEL LANGUAGE

AIM:

To write a program for token separation using high level language like python and java.

Tokenization using Python:

PROCEDURE:

1. Split the text into lines using the splitlines() method.


2. Iterate over the lines of text using the for loop.
3. For each line, tokenize the line using the tokenize.tokenize() function.
4. Append each token to the tokens list.
5. Return the tokens list.

PROGRAM CODE:

import re

def tokenize_text(text):
# Regular expression pattern to match whitespace and punctuation
pattern = r'\s+|[,.;!?"]'

# Use re.split() to tokenize the text


tokens = re.split(pattern, text)

# Remove empty tokens


tokens = [token for token in tokens if token]

return tokens
input_text = " S.I. = (P × R × T)/100"

# Tokenize the text


tokenized_result = tokenize_text(input_text)

# Print the tokens


print(tokenized_result)

Output :
Tokenization using Java:

Program:

import java.util.StringTokenizer;
public class TokenizationExample
{
public static void main(String[] args)
{
String input = "A bird in the hand is worth two in the bush.";

StringTokenizer tokenizer = new StringTokenizer(input, "+* ", true);


while (tokenizer.hasMoreTokens())
{
String token = tokenizer.nextToken().trim();
if (!token.isEmpty()) {
System.out.print("['" + token + "']");
}
}
}
}
Output :

RESULT:

Thus, we executed a program for token separation using high level language like python and java.
Exp No: 05
Date: STUDY OF LEX TOOL

Introduction:

 Lex is a program that generates lexical analyzer. It is used with YACC parser generator.
 The lexical analyzer is a program that transforms an input stream into a sequence of tokens.
 It reads the input stream and produces the source code as output through implementing the lexical
analyzer in the C program.

The function of Lex is as follows:

 Firstly lexical analyzer creates a program lex.1 in the Lex language. Then Lex compiler runs the lex.1
program and produces a C program lex.yy.c.
 Finally C compiler runs the lex.yy.c program and produces an object program a.out.
 a.out is lexical analyzer that transforms an input stream into a sequence of tokens.

Lex file format

A Lex program is separated into three sections by %% delimiters. The formal of Lex source is as follows:

1. { definitions }

2. %%

3. { rules }

4. %%

5. { user subroutines }

Definitions: Include declarations of constant, variable and regular definitions.

Rules: define the statement of form p1 {action1} p2 {action2}....pn {action}.

Where pi describes the regular expression and action1 describes the actions what action the
lexical analyzer should take when pattern pi matches a lexeme.
To run a lex program

1) Create a file, usually named lex.l, containing regular expressions and associated actions.
2) Define rules using the format: regex { action }.
3) Run lex tool using: lex lex.l
4) The Lex tool generates a C program named lex.yy.c.
5) Create a C program that includes lex.yy.c and provides the necessary code for the rest of
the compiler or interpreter.
6) Compile the C program: gcc lex.yy.c -o lexer -ll
7) Execute the generated lexer: ./lexer input_file.txt

RESULT:
Hence the study of LEX tool has been done successfully.
Exp No: 06 a
Date: COUNT OF POSITIVE AND NEGATIVE NUMBERS

AIM:

To write a Lex program for counting the positive and negative numbers.

PROCEDURE:

1. Include necessary headers.


2. Declare variables to store the counts of positive and negative numbers and a variable to hold the
user input.
3. Enter the number you want to display.
4. Display the results.

PROGRAM CODE:

%{

int positive_no = 0, negative_no = 0;

%}

%%

^[-][0-9]+ {negative_no++;

printf("negative number = %s\n",

yytext);} // negative number

[0-9]+ {positive_no++;

printf("positive number = %s\n",

yytext);} // positive number

%%

int yywrap(){}

int main()

yylex();

printf ("number of positive numbers = %d,"

"number of negative numbers = %d\n",

positive_no, negative_no);

return 0;

}
Output:

RESULT:

Thus, we executed a Lex program for counting the positive and negative numbers.
Exp No: 06 b
Date: COUNT OF NUMBER OF WORDS, CHARACTERS AND LINES

AIM:

To write a Lex program for counting number of words, characters and lines.

PROCEDURE:

1. Include Necessary Libraries.


2. Create variables to keep track of the word count, character count, and line count.
3. Prompt the user to enter the words, characters and lines.
4. Display the results.

PROGRAM CODE:

%{

#include<stdio.h>

int lc=0,sc=0,tc=0,ch=0,wc=0;

%%

[\n] { lc++; ch+=yyleng;}

[ \t] { sc++; ch+=yyleng;}

[^\t] { tc++; ch+=yyleng;}

[^\t\n ]+ { wc++; ch+=yyleng;}

%%

int yywrap(){ return 1; }

int main(){

printf("Enter the stream of text : ");

yylex();

printf("Number of lines : %d\n",lc);

printf("Number of spaces : %d\n",sc);

printf("Number of tabs, words, charc : %d , %d , %d\n",tc,wc,ch);

return 0;

}
Output:

RESULT:

Thus, we executed a Lex program for counting number of words, characters and lines.
Exp No: 06 c
Date: COUNT OF VOWELS AND CONSONANTS

AIM:

To write a Lex program for counting vowels and consonants.

PROCEDURE:

1. Include Necessary Libraries.


2. Declare variables to store the counts of vowels and consonants, and a variable to store the input
string.
3. Prompt the user to enter a string.
4. Count Vowels and Consonants.
5. Display the results.

PROGRAM CODE:

%{

int vow_count=0;

int const_count =0;

%}

%%

[aeiouAEIOU] {vow_count++;}

[a-zA-Z] {const_count++;}

%%

int yywrap(){}

int main()

printf("Enter the string of vowels and consonants:");

yylex();

printf("Number of vowels are: %d\n", vow_count);

printf("Number of consonants are: %d\n", const_count);

return 0;
}

Output:

RESULT:

Thus, we executed a Lex program for counting vowels and consonants.


Exp No: 06 d
Date: ODD OR EVEN

AIM:

To write a Lex program to decide whether number is odd or even.

PROCEDURE:

1. Include necessary C libraries.


2. function, which is the entry point of your program

3. Declare a variable to store the input number and get it from the user.

4. Compile and run the program.

PROGRAM CODE:

%{

#include<stdio.h>

int i;

%}

%%

[0-9]+ {i=atoi(yytext);

if(i%2==0)

printf("Even");

else

printf("Odd");}

%%

int yywrap(){}

int main()

yylex();

return 0;

}
Output:

RESULT:

Thus, we executed a Lex program to decide whether number is odd or even.


Exp No: 06 e
Date: EMAIL VALIDATION

AIM:

To write a Lex program for email validation.

PROCEDURE:

1. Include Necessary Headers.

2. Create a function that will validate the email address.

3. Define a regular expression pattern that represents a valid email address.

4. Compile and run.

PROGRAM CODE:

%{

#include<stdio.h>

#include<stdlib.h>

int flag=0;

%}

%%

[a-z . 0-9]+@[a-z]+".com"|".in"|".education" (flag=1; }

%%

int yywrap(){}

int main() {

printf("Enter Email Id :");

yylex();

if(flag==1)

printf("Valid \n");

else

printf("Not Valid \n");

}
Output:

RESULT:

Thus, we successfully executed a Lex program for email validation.


Exp No: 06 f
Date: VALIDATION OF DATE

AIM:

To write a Lex program for validation of dates and to identify whether they are valid or not.

PROCEDURE:

1. Include necessary C libraries.


2. Match date strings, convert components, and validate year, month, and day.
3. Print "Invalid date" if checks fail; otherwise, the date is valid.
4. For non-matching date formats, print "Invalid date format."
5. In `main()`, process an input file specified in the command line arguments or display usage
instructions if missing or inaccessible.

PROGRAM CODE:

%{

#include<stdio.h>

int valid=0;

%}

%%

([0-2][0-9]|3[0-1])\/(0[1-9]|1[0-2])\/([1-2][0-9][0-9][0-9]) {valid=1;}

%%

int main()

yyin=fopen("input.txt","r");

yylex();

if(valid==1) printf("It is a valid date\n");

else printf("It is not a valid date\n");

int yywrap()

return 1;

}
OUTPUT:

RESULT:

Hence, we have successfully executed a Lex program for validation of date.


Exp No: 06 g
Date: STRING STARTS WITH ‘a’

AIM:

To write a Lex program to determine if string starts with 'a' or not.

PROCEDURE:

1. This program will match any string that starts with the letter 'a'.
2. If the string matches this pattern, the program will print "String starts with 'a'."
3. Otherwise, it will print "String does not start with 'a'."
PROGRAM CODE:

%%

^a {

printf("String starts with 'a'.\n");}

.{

printf("String does not start with 'a'. \n");}

%%

int main() {

yylex();

return 0;}

Output:

RESULT:

Thus, we executed a Lex program to determine if string starts with 'a' or not.

Exp No: 06 h
Date: MOBILE NUMBER VALIDATION

AIM:

To write a Lex program for mobile number validation.

PROCEDURE:

1. Define the Validation Pattern:

Specify the pattern that a valid mobile number should follow. For example, it could be a 10-digit
number that starts with '7', '8', or '9'.

2. Create Rules:

Set up rules in your Lex program to check if the input matches the validation pattern. If it does, label
it as a valid mobile number; otherwise, label it as invalid.

3. Run and Check:

Compile your Lex program, run it, and provide mobile numbers for validation. The program will tell
you if each number is valid or not based on the rules you defined.

PROGRAM CODE:

%{

%}

%option noyywrap

%%

[1-9][0-9]{9} {printf("\nMobile Number Valid\n");}

.+ {printf("\nMobile Number Invalid\n");}

%%

int main()

printf("\nEnter Mobile Number : ");

yylex();

printf("\n");

return 0;

}
OUTPUT:

RESULT:

Hence, we have successfully executed a Lex program for mobile number validation.
Exp No: 06 i
Date: LEXICAL ANALYSER (Token Separation) USING LEX

AIM:

To write a Lex program for token separation.

PROCEDURE:

1. The Lex program for tokenizing C code will recognize the following tokens:
2. Floating point numbers: Strings of digits followed by a period followed by more digits.
3. Datatypes: The keywords int, float, char, double, and void.
4. Integer numbers: Strings of digits.
5. Functions: Strings of alphanumeric characters followed by parentheses.
6. Identifiers: Strings of alphanumeric characters.
7. Operators: The symbols +, -, *, and /.
8. Delimiters: The semicolon ;.
9. Separators: The comma ,.
10. Preprocessor directives: Strings that start with the hash symbol # followed by alphanumeric
characters and periods.

The program will read the input from the file test.c and tokenize it. It will then print the tokens to the
standard output, along with their type.

PROGRAM CODE:

%{

%}

%%

[0-9]+[.][0-9]+ printf("%s is a floating point number\n",yytext);

int|float|char|double|void printf("%s is a datatype\n",yytext);

[0-9]+ printf("%s is an integer number\n",yytext);

[a-z]+[()] printf("%s is a function\n",yytext);

[a-z]+ printf("%s is an identifier\n",yytext);

[+=*/-] printf("%s is an operator\n",yytext);

; printf("%s is an delimiter\n",yytext);

, printf("%s is a separator\n",yytext);

[#][a-z\.h]+ printf("%s is a preprocessor\n",yytext);

%%

int yywrap(void)

return 1;
}

int main()

// reads input from a file named test.c rather than terminal

freopen("test.c", "r", stdin);

yylex();

return 0;

Test.c:

OUTPUT:

RESULT:

Thus, we successfully executed a Lex program for token separation.


Exp No: 07
Date: STUDY OF YACC TOOL

YACC (Yet Another Compiler Compiler)," serves as a powerful grammar parser and generator. In essence, it
functions as a tool that takes in a grammar specification and transforms it into executable code capable of
meticulously structuring input tokens into a coherent syntactic tree, aligning seamlessly with the
prescribed grammar rules.

Stephen C. Johnson developed YACC in compiler design in the early 1970s. Initially, the YACC was written in
the B programming language and was soon rewritten in C. It was originally designed for being
complemented by Lex.

In addition to that, YACC was also rewritten in OCaml, Ratfor, ML, ADA, Pascal, Java < Python, Ruby and Go.

The input of YACC in compiler design is the rule or grammar, and the output is a C program.

Parts of a YACC Program in Compiler Design

The parts of YACC program are divided into three sections:

/* definitions */

....

%%

/* rules */

....

%%

/* auxiliary routines */

....

Definitions: these include the header files and any token information used in the syntax. These are located
at the top of the input file. Here, the tokens are defined using a modulus sign. In the YACC, numbers are
automatically assigned for tokens.

%token ID

{% #include <stdio.h> %}
Rules: The rules are defined between %% and %%. These rules define the actions for when the token is
scanned and are executed when a token matches the grammar.

Auxiliary Routines: Auxiliary routines contain the function required in the rules section. This Auxiliary
section includes the main() function, where the yyparse() function is always called.

This yyparse() function plays the role of reading the token, performing actions and then returning to the
main() after the execution or in the case of an error.

0 is returned after successful parsing and 1 is returned after an unsuccessful parsing.

The YACC is responsible for converting these sections into subroutines which will examine the inputs. This
process is made to work by a call to a low-level scanner and is named Parsing

Let us now study the working of YACC in compiler design.

Workings of YACC:

YACC in compiler design is set to work in C programming language along with its parser generator.

• An input with a .y extension is given.


• The file is invoked, and 2 files, y.tab.h and y.tab.c, are created. These files contain long
codes implementing the LARl (1) Parser for grammar.
• This file then provides yyparse.y, which tries to parse a valid sentence successfully.
 For the output files,
• If called with the –d option in the command line, YACC produces y.tab.h with all its
specific definitions.
• If called with the –v option, YACC produces y.output having a textual description of the
LALR(1) parsing table.
 How to Execute
• Save the program code to a file with a .y extension, such as calculator.y.
• Install Yacc/Bison on your system, if it is not already installed.
• Open a terminal or command prompt and navigate to the directory where the .y file is
saved.
• Run the following command to generate a C source file from the Yacc/Bison grammar
file
 yacc -d filename.y
• This will create two output files: y.tab.c (the C source file) and y.tab.h (the header file).
• Compile the generated C source file and link it with the Yacc/Bison runtime library using
a C compiler such as GCC:
 gcc -o calculator y.tab.c -ly
• Run the compiled program.

RESULT:

Hence the study of YACC tool has been done successfully.


Exp No: 08
Date: PARSER PROGRAM USING YACC

AIM:

To write a parser program using YACC tool.

PROCEDURE:

1. Lex (pp1.l) :
 Define token names for 'Zero' and 'One'.
 Create a set of regular expressions and corresponding actions to recognize 0 and 1 as
tokens, setting 'yylval' accordingly. Ignore whitespace characters.
 If none of the specified patterns match, return the ASCII value of the first character in
'yytext'.
2. Yacc (pp1.y) :
 Declare the tokens and define the grammar rules for recognizing sequences of 'Zero' and
'One'.
 In the 'main' function, call 'yyparse' to start parsing the input. If the parsing is successful,
print "Accepted." If there's an error during parsing, print "Not Accepted" and exit the
program.
3. Main Function:
 In the main function, call yyparse to initiate the parsing process.
 If the input string conforms to the defined grammar rules, the program prints
"Accepted."
 If there's a syntax error or if the input doesn't match the grammar, the yyerror function
is called, which prints "Not Accepted.

PROGRAM CODE:

Command: vi pp1.l

pp1.l

%{

#include<stdio.h>

#include "y.tab.h"

extern int yylval;

%}

%%

0 {yylval=0; return Zero;}

1 {yylval=1;return One;}

[ \t] return 0;\n return 0;

return yytext[0];

%%
pp1.y

%{

#include<stdio.h>

#include<stdlib.h>

#include "y.tab.h"

void yyerror(char *s);

int yylex();

%}

%token Zero One

%%

stmt:S;

S:SA | A;

A:Zero Zero | One One;

%%

int main()

{yyparse(); printf("Accepted\t");

exit(0);}

void yyerror(char *s)

(printf("Not Accepted\n");

exit(0);
OUTPUT:

RESULT:

Hence, we have successfully executed the parser program using YACC.


Exp No: 09
Date: CALCULATOR PROGRAM USING LEX AND YACC

AIM:

To write a calculator program using lex and yacc tool.

PROCEDURE:

1. Lexical Analysis (calculator.l):

 Define tokens for math functions (sin, cos, tan, etc.).


 Recognize patterns for these functions and handle numbers and whitespace.
 Return corresponding tokens for matched patterns.

2. Syntax Analysis (calculator.y):

 Specify grammar rules for mathematical expressions (E).


 Include arithmetic operations, function calls (e.g., sin, cos, tan), and math operations
(e.g., sqrt, log).
 Parse and evaluate expressions

3. Main Function:

 Prompt user for input and call `yyparse` to initiate parsing.


 Evaluate valid expressions and print results.
 Handle syntax errors through the `yyerror` function, which prints "Not accepted" and
exits the program.

PROGRAM CODE:

calculator.l for the Lex code:

%{

#include "y.tab.h"

%}

%%

[0-9]+ { yylval = atoi(yytext); return NUM; }

[-+*/\n] { return *yytext; }

[ \t] ;

. { yyerror("Invalid character"); }

%%

int yywrap() {

return 1;
}

calculator.y for the Yacc code:

%{

#include <stdio.h>

#include <stdlib.h>

%}

%token NUM

%left '+' '-'

%left '*' '/'

%%

calclist: /* empty */

| calclist exp '\n' { printf("Result: %d\n", $2); }

exp: NUM

| exp '+' exp { $$ = $1 + $3; }

| exp '-' exp { $$ = $1 - $3; }

| exp '*' exp { $$ = $1 * $3; }

| exp '/' exp {

if ($3 == 0) {

yyerror("Division by zero");

exit(1);

} else {

$$ = $1 / $3;

| '(' exp ')' { $$ = $2; }

%%

int main() {

yyparse();
return 0;

void yyerror(const char *s) {

fprintf(stderr, "%s\n", s);

Compile the program:

lex -o lex.yy.c calculator.l

yacc -d -o y.tab.c calculator.y

gcc lex.yy.c y.tab.c -o calculator -ll -ly

./calculator

INPUT:

OUTPUT:

RESULT:

Thus, we have successfully executed the calculator program using lex and yacc.
Exp No: 10
Date: THREE ADDRESS CODE GENERATION USING LEX AND YACC

AIM:

To write a three address code generation using lex and yacc.

PROCEDURE:

Generating Three Address Code using Lex and Yacc involves creating a parser that recognizes the input
language and generates the corresponding three-address code.

1) Create a file named three_address.l for the Lex code.


2) Create a file named three_address.y for the Yacc code.
3) Run the commands to generate the Lex and Yacc files and compile the program.
4) Enter simple arithmetic expressions and assignments, and the generator will print the
corresponding three-address code.

PROGRAM CODE:

three_address.l:

%{

#include "y.tab.h"

%}

DIGIT [0-9]

ID [a-zA-Z][a-zA-Z0-9]*

%%

[ \t\n] ;

"+" { return ADD; }

"-" { return SUB; }

"*" { return MUL; }

"/" { return DIV; }

"=" { return ASSIGN; }

"(" { return LPAREN; }

")" { return RPAREN; }

{DIGIT}+ { yylval.num = atoi(yytext); return NUM; }

{ID} { yylval.id = strdup(yytext); return IDENTIFIER; }

. { yyerror("Invalid character"); }
%%

int yywrap() {

return 1;

three_address.y:

%{

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

int yylex();

void yyerror(const char *s);

int temp_count = 1;

%}

%union {

int num;

char *id;}

%token <num> NUM

%token <id> IDENTIFIER

%token ADD SUB MUL DIV ASSIGN LPAREN RPAREN

%left ADD SUB

%left MUL DIV

%%

program: stmt_list

stmt_list:

| stmt_list statement '\n' { printf("%s", $2); }

statement:

| IDENTIFIER ASSIGN expr {

printf("%s = %s\n", $1, $3);

free($3);
}

expr: expr ADD term { $$ = generate_code($1, $3, "+"); }

| expr SUB term { $$ = generate_code($1, $3, "-"); }

| term { $$ = $1; }

term: term MUL factor { $$ = generate_code($1, $3, "*"); }

| term DIV factor { $$ = generate_code($1, $3, "/"); }

| factor { $$ = $1; }

factor: NUM { $$ = strdup(yytext); }

| IDENTIFIER { $$ = strdup(yytext); }

| LPAREN expr RPAREN { $$ = $2; }

%%

int main() {

yyparse();

return 0;}

void yyerror(const char *s) {

fprintf(stderr, "%s\n", s);}

char* generate_code(char* arg1, char* arg2, char* op) {

char temp[10];

sprintf(temp, "t%d", temp_count++);

printf("%s = %s %s %s\n", temp, arg1, op, arg2);

return strdup(temp);

}
commands to generate the Lex and Yacc files and compile the program:

lex -o lex.yy.c three_address.l

yacc -d -o y.tab.c three_address.y

gcc lex.yy.c y.tab.c -o three_address -ll -ly

./three_address

INPUT:

OUTPUT:

RESULT:

Hence the Three Address Code Generation using LEX and YACC was implemented successfully.
Exp No: 11
Date: CODE OPTIMIZER

AIM:

To develop a C program to optimize a given snip of code and get the optimized code as output

PROCEDURE:

1) Open any C compiler to write the code in C language.


2) Include all the necessary header files.
3) Define a structure with all the required variables to be used.
4) Write the main method and start to write all the required logics:
•First: get the user input in left and right form where left indicates the left operand and
right indicates the right operand.
• Second: Bring the intermediate code where all the operands and operators are combined
together and displayed.
5) Eliminate the common expressions and perform dead code elimination.
6) Print the optimized code.
7) Stop the program.

PROGRAM CODE:

#include<stdio.h>

#include<string.h>

struct op

char l;

char r[20];

op[10], pr[10];

int main ()

int a, i, k, j, n, z = 0, m, q;

char *p, *l;

char temp, t;

char *tem;

printf ("Enter the Number of Values: ");

scanf ("%d", &n);


for (i = 0; i < n; i++)

printf ("Enter left for item %d: ", i + 1);

scanf (" %c", &op[i].l); // space added before %c to consume the newline character

printf ("Enter right for item %d: ", i + 1);

scanf ("%s", op[i].r);

printf ("\n\nIntermediate Code\n");

for (i = 0; i < n; i++)

printf ("%c=", op[i].l);

printf ("%s\n", op[i].r);

for (i = 0; i < n - 1; i++)

temp = op[i].l;

for (j = 0; j < n; j++)

p = strchr (op[j].r, temp);

if (p)

pr[z].l = op[i].l;

strcpy (pr[z].r, op[i].r);

z++;

pr[z].l = op[n - 1].l;

strcpy (pr[z].r, op[n - 1].r);

z++;
printf ("\nAfter Dead Code Elimination\n");

for (k = 0; k < z; k++)

printf ("%c \t=", pr[k].l);

printf ("%s\n", pr[k].r);

for (m = 0; m < z; m++)

tem = pr[m].r;

for (j = m + 1; j < z; j++)

p = strstr (tem, pr[j].r);

if (p)

t = pr[j].l;

pr[j].l = pr[m].l;

for (i = 0; i < z; i++)

l = strchr (pr[i].r, t);

if (l)

a = l - pr[i].r;

printf ("pos: %d\n", a);

pr[i].r[a] = pr[m].l;

printf ("Eliminate Common Expression\n");


for (i = 0; i < z; i++)

printf ("%c\t=", pr[i].l);

printf ("%s\n", pr[i].r);

for (i = 0; i < z; i++)

for (j = i + 1; j < z; j++)

q = strcmp (pr[i].r, pr[j].r);

if ((pr[i].l == pr[j].l) && !q)

pr[i].l = '\0';

printf ("Optimized Code\n");

for (i = 0; i < z; i++)

if (pr[i].l != '\0')

printf ("%c=", pr[i].l);

printf ("%s\n", pr[i].r); } }

return 0;}
INPUT:

OUTPUT:

RESULT:

Thus, a C program for code optimization has been developed and executed successfully.
Exp No: 12
Date: CODE GENERATION

AIM:

To develop a C program to generate assembly code from three address code using C language.

PROCEDURE:

1.Open any C compiler to write the code for code generation in C language.

2. Include all the necessary header files.

3. Define a structure for storing the required variables.

4. Declare variables such as n, i, j, and the character array a to store intermediate codes.

5. Request the user to input the number of intermediate codes.

6. Use a nested loop to gather the 3-address intermediate codes. The outer loop handles each

code, and the inner loop reads each character of the code.

7. Write the main method to get the input from the user and generate code, assemble them in

proper order.

8. Display the finally generated assembly language code. Compile the entire code in C compiler

and then obtain the output. Stop the program.

PROGRAM CODE:

#include<stdio.h>

#include<conio.h>

#include<string.h>

void main()

int n,i,j;

char a[50][50];

printf("Enter the number of intermediate codes:");

scanf("%d",&n);

for(i=0;i<n;i++)

printf("Enter the 3 address code: %d ",i+1);


for(j=0;j<6;j++)

scanf("%c",&a[i][j]);}

printf("The generated code is: ");

for(i=0;i<n;i++)

printf("\nMov %c,R%d",a[i][3],i);

if(a[i][4]=='-')

printf("\nSub %c,R%d",a[i][5],i);}

if(a[i][4]=='+')

printf("\nAdd %c,R%d",a[i][5],i);}

if(a[i][4]=='*')

printf("\nMul %c,R%d",a[i][5],i);}

if(a[i][4]=='/')

printf("\nDiv %c,R%d",a[i][5],i);}

printf("\nMov R%d, %c",i,a[i][1]);

printf("\n");

getch();

INPUT:
OUTPUT:

RESULT:

Thus, a C program for code generation has been developed and executed successfully

You might also like