Shri Vaishnav Vidyapeeth Vishwavidyalaya, Indore
Shri Vaishnav Institute of Information Technology
Department of Computer Science & Engineering
LAB FILE
Subject: Compiler Design
Course Code: BTCS601N
III-Year/VI-Semester - Section (M+P)
Submitted By:- Submitted to:-
Name: Tarishi Chouhan Dr.Harsh Pratap Singh
Enrollment Number: 21100BTAIMLM09381 (Assistant Professor)
Subject Name -Compiler Design Subject Code- BTCS601N
Index
Compiler Design
S.No. Name of the Experiment Date Remark
1. WAP to count the number of operators in an expression. 6-2-24
2. WAP to recognize the tokens using C Language. 20-2-24
3. 20-2-24
Write a program to implement DFA that recognize
identifier, constant and operator of the mini-language.
4. Write a program to check whether a given string follow the 5-3-24
given pattern (0+1)1*.
5. Write a program to implement given DFA (00 + 1)*. 5-3-24
6. Write a program to implement a DFA for the language 12-3-24
L = {(01)i12i , i>=1, j>=1}.
7. WAP to implement Recursive Descent Parser. 12-3-24
8. WAP to Calculate the First( ) set of any Grammar. 26-3-24
9. WAP to Calculate the Follow ( ) set of any Grammar. 26-3-24
10. WAP to design Predictive Parser for any Grammar. 2-4-24
11. WAP to design LALR(1) Parser for any Grammar. 16-4-24
12. 23-4-24
WAP to generate machine code from the abstract Syntax
Tree generated by theparser.
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 2
Subject Name -Compiler Design Subject Code- BTCS601N
Experiment-01
Aim - WAP to count the number of operators in an expression.
Description:
1. Expression: An expression is a combination of symbols (operands) and operators that
represents a value. Expressions can be simple or complex and can involve arithmetic,
logical, relational, or other types of operations.
2. Components of an Expression:
• Operands: The values or variables on which operations are performed.
• Operators: Symbols representing specific operations.
3. Operators: Operators are symbols that represent specific operations such as addition
(+), subtraction (-), multiplication (*), division (/), logical operations (AND, OR),
comparison operations (>, <, =), etc.
4. Types of Operators:
• Arithmetic Operators: Perform arithmetic operations.
• Logical Operators: Perform logical operations.
• Comparison Operators: Perform comparison operations.
• Assignment Operators: Assign values.
Algorithm:
Algorithm to count operators in an expression:
1. Initialize a variable `operatorCount` to 0.
2. For each character `c` in the expression:
a. If `c` is an operator (e.g., '+', '-', '*', '/', '%', '^'):
i. Increment `operatorCount` by 1.
3. Return `operatorCount`.
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 3
Subject Name -Compiler Design Subject Code- BTCS601N
Program:
#include<stdio.h>
int main()
int a,count=0;
printf("Enter the number of characters in the expression::\n");
scanf("%d",&a);
char c[a];
printf("Enter the expression::");
for(int i=0;i<a;i++)
scanf("%c",&c[i]);
if(c[i]=='+' || c[i]=='-' || c[i]=='*' || c[i]=='>' || c[i]=='<' || c[i]=='/' || c[i]=='=')
count++;
printf("The number of operators in the expression are: %d",count);
return 0;
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 4
Subject Name -Compiler Design Subject Code- BTCS601N
Output:
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 5
Subject Name -Compiler Design Subject Code- BTCS601N
Experiment-02
Aim: - WAP to recognize the tokens using C Language.
Description:
Tokens:
In programming languages, tokens are the smallest units of a program. These units can be
identifiers, keywords, constants, operators, punctuation symbols, etc.
Types of Tokens:
Keywords: Reserved words with predefined meanings in the language.
Identifiers: Names given to entities such as variables, functions, etc.
Constants: Literal values that do not change during program execution.
Operators: Symbols that represent specific operations.
Punctuation Symbols: Characters like commas, semicolons, braces, etc.
Special Symbols: Specific characters with special meaning, such as the dot operator or arrow
operator in C.
Token Recognition:
Token recognition involves scanning the source code character by character and identifying
the tokens based on predefined rules and patterns.
Lexical analysis is the process of converting the sequence of characters into meaningful
tokens.
Lexical Analysis Process:
Lexical Analysis is the first phase of the compiler also known as a scanner. It converts the
High level input program into a sequence of Tokens.
Lexical Analysis can be implemented with the Deterministic finite Automata.
The output is a sequence of tokens that is sent to the parser for syntax analysis.
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 6
Subject Name -Compiler Design Subject Code- BTCS601N
Algorithm:
Algorithm: TokenRecognition
Input: sourceCode (string)
Output: tokens (array of tuples containing token type and value)
1. Initialize an empty array tokens to store recognized tokens.
2. Define regular expressions or rules to recognize different types of tokens:
- Keywords: Use a list of reserved keywords in C.
- Identifiers: Start with a letter or underscore, followed by letters, digits, or underscores.
- Constants: Integers, floating-point numbers, character literals, or string literals.
- Operators: Arithmetic, relational, logical, assignment, etc.
- Punctuation Symbols: Semicolon, comma, parentheses, braces, etc.
3. Iterate through the source code character by character:
a. Skip whitespace characters.
b. Check if the current character matches any of the defined token patterns.
c. If a match is found:
- Determine the type of token.
- Extract the token value.
- Add the token type and value to the tokens array.
d. Move to the next character and repeat steps b-c until the end of the source code.
4. Return the array of recognized tokens.
Program:
#include <stdio.h>
#include <ctype.h>
#include <string.h>
int main() {
char input[100];
printf("Enter an input string: ");
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 7
Subject Name -Compiler Design Subject Code- BTCS601N
fgets(input, 100, stdin);
int len = strlen(input); char token[len];
int i = 0, j = 0; while (i < len) {
if (isalpha(input[i])) { token[j++] = input[i++];
while (i < len && isalnum(input[i])) { token[j++] = input[i++];
token[j] = '\0';
printf("Identifier: %s\n", token); j = 0;
} else if (isdigit(input[i])) { token[j++] = input[i++];
while (i < len && isdigit(input[i])) { token[j++] = input[i++];
token[j] = '\0';
printf("Integer: %s\n", token); j = 0;
} else if (ispunct(input[i])) { printf("Symbol: %c\n", input[i++]);
} else if (isspace(input[i])) { i++;
} else {
printf("Unknown character: %c\n", input[i++]);
return 0;
Output:
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 8
Subject Name -Compiler Design Subject Code- BTCS601N
Experiment-03
Aim:- Write a program to implement DFA that recognize identifier,
constant and operator of the mini-language.
Description:
The DFA serves as a mathematical model to recognize patterns in strings. It consists of states,
input symbols, transitions, a start state, and one or more accepting states. Each state
represents a specific stage of recognition for identifiers, constants, or operators. Transitions
guide the DFA's traversal through the input string based on the current input character and
state. Accepting states indicate successful recognition of a token.
Implementation involves defining states for recognizing identifiers, constants, and operators,
along with transitions between these states based on input characters. A transition function or
table guides the DFA's traversal through the input string.
Algorithm:
Input: inputString (string)
Output: tokenType (string), tokenValue (string)
1.Define DFA States:
Define states for recognizing identifiers, constants, and operators. For example, "Start",
"Identifier", "Constant", "Operator", etc.
2.Define the Alphabet:
Define the alphabet of input symbols, including letters, digits, and specific symbols
representing operators.
3.Define Accepting States:
Designate specific states as accepting states where recognition for identifiers, constants, or
operators is complete.
4.Construct Transition Table:
Define a transition table that maps the current state and input symbol to the next state.
Define transitions for each state and input symbol combination based on the rules of the mini-
language. For example:
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 9
Subject Name -Compiler Design Subject Code- BTCS601N
If the current state is "Start" and the input symbol is a letter, transition to the "Identifier"
state.
If the current state is "Identifier" and the input symbol is a digit, remain in the "Identifier"
state.
If the current state is "Identifier" and the input symbol is not a valid character for identifiers,
transition to the "Error" state.
5.Initialize Variables:
Initialize currentState to "Start".
Initialize tokenType and tokenValue to empty strings.
6.Process Input String:
Iterate through each character char in the inputString:
a. Determine the input symbol category (letter, digit, operator, etc.) for char.
b. Look up the transition from the currentState and input symbol category in the transition
table.
c. Update the currentState based on the transition.
d. Append char to tokenValue.
e. If the currentState is an accepting state, update tokenType based on the currentState.
7.Check Final State:
If the currentState is an accepting state, return tokenType and tokenValue as the recognized
token.
If the currentState is not an accepting state, return an error indicating an unrecognized token.
Program:
#include <stdio.h>
#include <ctype.h>
#define MAX_STATE 4 // Number of states in the DFA
// Function prototypes for state transitions
int is_identifier_start(char ch);
int is_identifier_char(char ch);
int is_digit(char ch);
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 10
Subject Name -Compiler Design Subject Code- BTCS601N
int is_operator(char ch);
int main() {
char input[100];
printf("Enter a string: ");
scanf("%s", input);
int state = 0; // Start state
for (int i = 0; input[i] != '\0'; i++) {
char ch = input[i];
switch (state) {
case 0: // Start state
if (is_identifier_start(ch)) {
state = 1; // Identifier state
} else if (is_digit(ch)) {
state = 2; // Constant state
} else if (is_operator(ch)) {
printf("Operator: %c\n", ch);
} else {
printf("Invalid character: %c\n", ch);
return 1; // Error
break;
case 1: // Identifier state
if (is_identifier_char(ch)) {
// Stay in identifier state
} else {
printf("Identifier: %.*s\n", i, input); // Print identified string
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 11
Subject Name -Compiler Design Subject Code- BTCS601N
state = 0; // Back to start state
i--; // Re-process the character that caused the exit
break;
case 2: // Constant state
if (is_digit(ch)) {
// Stay in constant state
} else {
printf("Constant: %.*s\n", i, input); // Print identified constant
state = 0; // Back to start state
i--; // Re-process the character that caused the exit
break;
default:
printf("Internal error: Unknown state %d\n", state);
return 1; // Error
if (state == 1) {
printf("Identifier: %s\n", input); // Handle identifier at string end
} else if (state == 2) {
printf("Constant: %s\n", input); // Handle constant at string end
return 0;
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 12
Subject Name -Compiler Design Subject Code- BTCS601N
// Check if character is a valid starting character for an identifier
int is_identifier_start(char ch) {
return isalpha(ch) || ch == '_';
// Check if character is a valid character for an identifier or constant
int is_identifier_char(char ch) {
return isalnum(ch) || ch == '_';
// Check if character is a digit
int is_digit(char ch) {
return isdigit(ch);
// Check if character is a valid operator (replace with your mini-language's operators)
int is_operator(char ch) {
return ch == '+' || ch == '-' || ch == '*' || ch == '/';
Output:
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 13
Subject Name -Compiler Design Subject Code- BTCS601N
Experiment-04
Aim: - Write a program to check whether a given string follow the given
pattern(0+1)1*.
Description:
Given string follows the given pattern (0+1)1*, which means the string starts with either "0"
or "1" followed by one or more occurrences of "1".
• 0 and 11: These are the literal characters representing the digits "0" and "1"
respectively.
• +: This represents the choice operator, meaning either "0" or "1".
• 1∗: This represents one or more occurrences of the character "1".
Algorithm:
function followsPattern(s):
if s[0] is not '0' and s[0] is not '1':
return false
for each character c in s starting from index 1:
if c is not '1':
return false
return true
Program:
#include <iostream>
#include<string>
using namespace std ;
bool dfa(string s )
int n = s.length() ;
if(s[0]!='0' && s[0]!='1')
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 14
Subject Name -Compiler Design Subject Code- BTCS601N
return false ;
for(int i = 1 ;i<n;i++)
if(s[i]=='1') continue ;
else
return false;
return true ;
int main()
int n = 4 ;
string s[n]= {"110","111","0111","010101","10111"} ;
cout<<"L->(0 + 1)1* "<<endl;
for(auto it : s)
if(dfa(it))
cout<<it<<" yes, it is valid pattern"<<endl;
else
cout<<it<<" No , it is not a valid pattern"<<endl;
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 15
Subject Name -Compiler Design Subject Code- BTCS601N
return 0;
Output:
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 16
Subject Name -Compiler Design Subject Code- BTCS601N
Experiment-05
Aim:- Write a program to implement given DFA (00 + 1)*.
Description:
(00+1) ∗represents a language consisting of strings containing alternating sequences of "00"
and "1", with any number of repetitions including zero.
The DFA involves states representing different stages of pattern recognition, transitions
guiding the DFA through the input based on encountered characters, and accepting states
indicating successful recognition.
Algorithm:
1. Start
2. Declare an array of strings s containing the input patterns.
3. Initialize the number of patterns n (in this case, n = 5).
4. For each pattern it in the array s, do the following:
o Check if the first character of it is either '0' or '1'. If not, return false.
o Initialize a counter variable count to zero.
o Iterate through each character in it:
▪ If the character is '1', continue to the next character.
▪ If the character is '0', keep counting consecutive zeros until a non-zero
character is encountered.
▪ Check if the count of consecutive zeros is even. If not, return false.
5. Return true if all patterns pass the checks, otherwise return false.
6. Stop
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 17
Subject Name -Compiler Design Subject Code- BTCS601N
Program:
#include <iostream>
#include<string>
using namespace std ;
bool dfa(string s){
if(s[0]!='0' && s[0]!='1')
return false; int n =s.length() ;
if(n==1 && s[0]=='1')
return true;
if(n==1 && s[0]=='0')
return false; int count = 0 ;
for(int i = 0 ;i<n ;i++){ if(s[i]=='1')continue ;
while(s[i]=='0')
count++; i++;
if(count % 2 != 0 )
return false ;
return true ;
int main()
int n = 5;
string s[n]= {"00101","00111","11111","10010","110011"};
cout<<"L->(00+1)* "<<endl; for(auto it : s)
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 18
Subject Name -Compiler Design Subject Code- BTCS601N
if(dfa(it))
cout<<it<<" yes, it is valid pattern"<<endl;
else
cout<<it<<" No , it is not a valid pattern"<<endl;
return 0;
Output:
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 19
Subject Name -Compiler Design Subject Code- BTCS601N
Experiment-06
Aim: Write a program to implement a DFA for the language
L = {(01)i12i , i>=1, j>=1}
Description:
The language L consists of strings that start with the pattern "01" repeated at least once (i >=
1), followed by exactly two "1"s, and then end with the same pattern "01" repeated the same
number of times as it appeared initially (2i).
Algorithm:
1. Initialization (performed in main function)
o Define the language L = {(01)^i 1^2j | i >= 1, j >= 1}.
o Create an array of strings s containing test cases.
2. Function Calls (in main function)
o Iterate through each string it in the s array.
o Call the checkstatea function with the current string it to initiate the state
checking process.
3. State Checking Functions
o checkstatea(string n):
▪ Check if the string length is even and greater than or equal to 4. If not, reject
the string (length requirement).
▪ If the first character is '0', call stateb(n.substr(1)).
▪ If the first character is not '0', reject the string (invalid starting symbol).
o stateb(string n):
▪ Check if the first character is '1'. If not, reject the string (invalid second
character).
▪ If the first character is '1', call statec(n.substr(1)).
o statec(string n):
▪ Check if the first character is '1'.
▪ If yes, call stated(n.substr(1)) to process the first '1' in the sequence.
▪ If no, call stateb(n.substr(1)) to start a new '01' repetition.
o stated(string n):
▪ Check if the string length is 1.
▪ If yes, check if the character is '1'.
▪ If yes, accept the string (valid ending with two '1's).
▪ If no, reject the string (invalid ending character).
▪ If no, check if the first character is '1'.
▪ If yes, call statee(n.substr(1)) to process subsequent '1's.
▪ If no, reject the string (invalid character).
o statee(string n):
▪ Check if the string length is 1.
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 20
Subject Name -Compiler Design Subject Code- BTCS601N
▪ If yes, check if the character is '0'.
▪ If no, reject the string (invalid ending character).
▪ If yes, accept the string (valid ending with '01' repetitions and two '1's).
▪ If no, check if the first character is '0'.
▪ If yes, reject the string (invalid character).
▪ If no, call stated(n.substr(1)) to process subsequent '1's in the second
half of the pattern.
Program:
#include <iostream>
#include <string>
using namespace std;
void checkstatea(string);
void stateb(string);
void statec(string);
void stated(string);
void statee(string);
void checkstatea(string n)
if (n.length() % 2 != 0 || n.length() < 4)
cout << "String Not Accepted" << endl;
else
int i = 0;
if (n[i] == '0')
stateb(n.substr(1));
else
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 21
Subject Name -Compiler Design Subject Code- BTCS601N
cout << "String Not Accepted" << endl;
void stateb(string n)
int i = 0;
if (n[i] == '0')
cout << "String Not Accepted" << endl;
else
statec(n.substr(1));
void statec(string n)
int i = 0;
if (n[i] == '1')
stated(n.substr(1));
else
stateb(n.substr(1));
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 22
Subject Name -Compiler Design Subject Code- BTCS601N
void stated(string n)
int i = 0;
if (n.length() == 1)
if (n[i] == '1')
cout << "String Accepted" << endl;
else
cout << "String Not Accepted" << endl;
else
if (n[i] == '1')
statee(n.substr(1));
else
cout << "String Not Accepted" << endl;
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 23
Subject Name -Compiler Design Subject Code- BTCS601N
void statee(string n)
int i = 0;
if (n.length() == 1)
if (n[i] == '0')
cout << "String Not Accepted" << endl;
else
cout << "String Accepted" << endl;
else
if (n[i] == '0')
cout << "String Not Accepted" << endl;
else
stated(n.substr(1));
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 24
Subject Name -Compiler Design Subject Code- BTCS601N
int main()
int n = 4;
cout<<"L = {(01)^i 1^2j | i>=1 ,j>=1"<<endl;
string s[] = {"011111","010111","111111","0011"};
for(auto it :s)
cout<<it<<" ";
checkstatea(it);
return 0;
Output:
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 25
Subject Name -Compiler Design Subject Code- BTCS601N
Experiment-07
Aim:- WAP to implement Recursive Descent Parser.
Description:
A top-down parser is known as a recursive descent parser that analyses input based on grammar
rules using recursive methods. Starting with the grammar's topmost rule, the parser executes
subroutines backward for each input symbol that is not a terminal symbol until it reaches one.
A parse tree representing the input's structure according to the grammar is the parser's output.
Algorithm:
• Main Function:
• Prints the grammar.
• Prompts the user for input.
• Calls the E function to initiate parsing.
• Checks if the input is completely parsed (input[i] == '\0') and prints an
"accepted" or "not accepted" message based on the result of E.
• Parsing Functions:
• E function:
o Calls T to parse a term.
o Calls EP to parse the optional +TE' part.
o Returns 1 if both T and EP succeed (entire E parsed).
o Returns 0 otherwise (failure).
• EP function:
o Checks if the current input character is '+'.
o If yes, increments i and calls T and EP recursively.
o Returns 1 if '+' is found and further parsing succeeds.
o Returns 1 even if no '+' is found (epsilon case, empty string).
• T and TP functions: (similar structure to E and EP)
o Call F to parse a factor.
o Call TP to parse the optional *FT' part.
o Return 1 if both F and TP succeed, 0 otherwise.
• F function:
o Handles three cases:
▪ '(' followed by a parsed expression E and ')' (parenthesized expression).
▪ An identifier character (a-z or A-Z).
o Increments i after successful parsing in each case.
o Returns 1 if parsing succeeds, 0 otherwise.
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 26
Subject Name -Compiler Design Subject Code- BTCS601N
Program:
#include<stdio.h>
#include<string.h>
char input[100];
int i;
int E();
int F();
int EP();
int T();
int TP();
int main()
printf("\nRecursive descent parsing for the following grammar\n");
printf("\nE -> TE'\nE' -> +TE'/ε\nT -> FT'\nT' -> *FT'/ε\nF -> (E)/ID\n");
printf("\nEnter the string to be checked:");
fgets(input, sizeof(input), stdin);
if(E()) {
if(input[i] == '\0' || input[i] == '\n') {
printf("\nString is accepted\n");
} else {
printf("\nString is not accepted\n");
} else {
printf("\nString not accepted\n");
return 0;
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 27
Subject Name -Compiler Design Subject Code- BTCS601N
int E() {
if(T()) {
if(EP()) {
return 1;
return 0;
int EP() {
if(input[i] == '+') {
i++;
if(T()) {
if(EP()) {
return 1;
return 0;
return 1; // Return 1 if epsilon (empty string)
int T() {
if(F()) {
if(TP()) {
return 1;
return 0;
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 28
Subject Name -Compiler Design Subject Code- BTCS601N
int TP() {
if(input[i] == '*') {
i++;
if(F()) {
if(TP()) {
return 1;
return 0;
return 1; // Return 1 if epsilon (empty string)
int F() {
if(input[i] == '(') {
i++;
if(E()) {
if(input[i] == ')') {
i++;
return 1;
return 0;
} else if((input[i] >= 'a' && input[i] <= 'z') || (input[i] >= 'A' && input[i] <= 'Z')) {
i++;
return 1;
} else {
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 29
Subject Name -Compiler Design Subject Code- BTCS601N
return 0;
Output:
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 30
Subject Name -Compiler Design Subject Code- BTCS601N
Experiment-08
Aim:- WAP to Calculate the First( ) set of any Grammar.
Description:
FIRST ()− It is a function that gives the set of terminals that begin the strings derived from the
production rule.
A symbol c is in FIRST (α) if and only if α ⇒ cβ for some sequence β of grammar symbols.
Computation of FIRST
FIRST (α) is defined as the collection of terminal symbols which are the first letters of strings
derived from α.
FIRST (α) = {α |α →∗ αβ for some string β }
If X is Grammar Symbol, then First (X) will be −
• If X is a terminal symbol, then FIRST(X) = {X}
• If X → ε, then FIRST(X) = {ε}
• If X is non-terminal & X → a α, then FIRST (X) = {a}
• If X → Y1, Y2, Y3, then FIRST (X) will be
(a) If Y is terminal, then
FIRST (X) = FIRST (Y1, Y2, Y3) = {Y1}
(b) If Y1 is Non-terminal and
If Y1 does not derive to an empty string i.e., If FIRST (Y1) does not contain ε then, FIRST
(X) = FIRST (Y1, Y2, Y3) = FIRST(Y1)
(c) If FIRST (Y1) contains ε, then.
FIRST (X) = FIRST (Y1, Y2, Y3) = FIRST(Y1) − {ε} ∪ FIRST(Y2, Y3)
Similarly, FIRST (Y2, Y3) = {Y2}, If Y2 is terminal otherwise if Y2 is Non-terminal then
• FIRST (Y2, Y3) = FIRST (Y2), if FIRST (Y2) does not contain ε.
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 31
Subject Name -Compiler Design Subject Code- BTCS601N
• If FIRST (Y2) contain ε, then
• FIRST (Y2, Y3) = FIRST (Y2) − {ε} ∪ FIRST (Y3)
Similarly, this method will be repeated for further Grammar symbols, i.e., for Y4, Y5, Y6 … .
YK.
Algorithm:
function compute_FIRST_sets(grammar):
Initialize empty FIRST sets for all non-terminal symbols
repeat
for each production rule in grammar:
if rule starts with terminal symbol:
add terminal symbol to FIRST set of corresponding non-terminal
else if rule starts with non-terminal symbol:
compute FIRST set recursively for the non-terminal
add non-epsilon symbols in FIRST set to FIRST set of original non-terminal
if epsilon is in FIRST set of non-terminal:
add epsilon to FIRST set of original non-terminal
until no new symbols are added to any FIRST set
Program:
#include <stdio.h>
#include <ctype.h>
void FIRSTfunc(char);
int count, n = 0;
char prodn[10][10],
firstTerms[10];
int main(){
int i, choice;
char c, ch;
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 32
Subject Name -Compiler Design Subject Code- BTCS601N
printf("How many productions ? :");
scanf("%d", &count);
printf("Enter %d productions epsilon= $ :\n\n", count);
for (i = 0; i < count; i++)
scanf("%s%c", prodn[i], &ch);
do {
n = 0;
printf("Element :");
scanf("%c", &c);
FIRSTfunc(c);
printf("\n FIRST(%c)= { ", c);
for (i = 0; i < n; i++)
printf("%c ", firstTerms[i]);
printf("}\n");
printf("press 1 to continue : ");
scanf("%d%c", &choice, &ch);
while (choice == 1);
void FIRSTfunc(char c)
int j;
if (!(isupper(c)))
firstTerms[n++] = c;
for (j = 0; j < count; j++)
if (prodn[j][0] == c)
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 33
Subject Name -Compiler Design Subject Code- BTCS601N
if (prodn[j][2] == '$')
firstTerms[n++] = '$';
else if(islower(prodn[j][2])); // A--> a or A-->B firstTerms[n++] = prodn[j][2];
else FIRSTfunc(prodn[j][2]);
Output:
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 34
Subject Name -Compiler Design Subject Code- BTCS601N
Experiment-09
Aim:- WAP to Calculate the Follow ( ) set of any Grammar.
Description:
A terminal symbol a is in FOLLOW (N) if and only if there is a derivation from the start symbol
S of the grammar such that S ⇒ αNαβ, where α and β are a (possible empty) sequence of
grammar symbols. In other words, a terminal c is in FOLLOW (N) if c can follow N at some
point in a derivation.
Computation of FOLLOW
Follow (A) is defined as the collection of terminal symbols that occur directly to the right
of A.
FOLLOW(A) = {a|S ⇒* αAaβ where α, β can be any strings}
Rules to find FOLLOW
• If S is the start symbol, FOLLOW (S) ={$}
• If production is of form A → α B β, β ≠ ε.
(a) If FIRST (β) does not contain ε then, FOLLOW (B) = {FIRST (β)}
Or
(b) If FIRST (β) contains ε (i. e. , β ⇒* ε), then
FOLLOW (B) = FIRST (β) − {ε} ∪ FOLLOW (A)
∵ when β derives ε, then terminal after A will follow B.
• If production is of form A → αB, then Follow (B) ={FOLLOW (A)}.
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 35
Subject Name -Compiler Design Subject Code- BTCS601N
Algorihtm:
function compute_FOLLOW_sets(grammar):
Initialize empty FOLLOW sets for all non-terminal symbols
Set the FOLLOW set of the start symbol to contain the end-of-string marker ($)
repeat
for each production rule in grammar:
for each non-terminal symbol in the rule:
if non-terminal symbol is at end of rule:
add FOLLOW set of left-hand side non-terminal symbol to its FOLLOW set
else:
compute FIRST set of sequence following non-terminal symbol
if epsilon is in FIRST set:
add FOLLOW set of left-hand side non-terminal symbol to FOLLOW set of
current non-terminal symbol
remove epsilon from FIRST set
add remaining symbols in FIRST set to FOLLOW set of current non-terminal
symbol
until no new symbols are added to any FOLLOW set
Program:
#include <stdio.h>
#include <iostream>
#include <string.h>
int n, m = 0, p, i = 0, j = 0;
char a[10][10],
followResult[10];
void follow(char c);
void first(char c);
void addToResult(char);
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 36
Subject Name -Compiler Design Subject Code- BTCS601N
int main()
int i;
int choice;
char c, ch;
printf("Enter the no.of productions: ");
scanf("%d", &n);
printf(" Enter %d productions\nProduction with multiple terms should be give as separate
productions \n", n);
for (i = 0; i < n; i++)
scanf("%s%c", a[i], &ch);
// gets(a[i]); do
m = 0;
printf("Find FOLLOW of -->");
scanf(" %c", &c);
follow(c);
printf("FOLLOW(%c) = { ",
c); for (i = 0; i < m; i++)
printf("%c ", followResult[i]);
printf(" }\n");
printf("Do you want to continue(Press 1 to continue )?");
scanf("%d%c", &choice, &ch);
while (choice == 1);
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 37
Subject Name -Compiler Design Subject Code- BTCS601N
void follow(char c)
if (a[0][0] == c)
addToResult('$');
for (i = 0; i < n; i++)
for (j = 2; j < strlen(a[i]); j++)
if (a[i][j] == c)
if (a[i][j + 1] != '\0')
first(a[i][j + 1]);
if (a[i][j + 1] == '\0' && c != a[i][0])
follow(a[i][0]);
void first(char c)
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 38
Subject Name -Compiler Design Subject Code- BTCS601N
int k;
if (!(isupper(c)))
// f[m++]=c; addToResult(c);
for (k = 0; k < n; k++)
if (a[k][0] == c)
if (a[k][2] == '$')
follow(a[i][0]);
else if (islower(a[k][2]))
// f[m++]=a[k][2];
addToResult(a[k][2]);
else
first(a[k][2]);
void addToResult(char c)
int i;
for (i = 0; i <= m; i++)
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 39
Subject Name -Compiler Design Subject Code- BTCS601N
if (followResult[i] == c)
return;
followResult[m++] = c;
Output:
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 40
Subject Name -Compiler Design Subject Code- BTCS601N
Experiment-10
Aim:- WAP to design Predictive Parser for any Grammar.
Descritption:
A predictive parser is a recursive descent parser that does not require backtracking or backup.
It operates in a top-down manner, meaning it starts from the root of the parse tree and works
its way down to the leaves.
Unlike some other parsing techniques, predictive parsing avoids backtracking, making it
efficient and deterministic.
How Predictive Parsing Works:
The predictive parser predicts which production rule to apply based on the current input symbol
(terminal).
It uses a look-ahead pointer to determine the next input symbol.
At each step, the choice of the rule to be expanded is made solely based on the next terminal
symbol.
For example, consider the grammar rule: A -> A1 | A2 | ... | An. If the non-terminal A is to be
further expanded, the rule is selected based on the current input symbol a.
Example Grammar: Consider the following grammar:
E -> E + T | T
T -> T * F | F
F -> (E) | id
We create transition diagrams for each rule.
Optimize the DFA by combining structures.
Simulate the input string using the DFA to parse it.
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 41
Subject Name -Compiler Design Subject Code- BTCS601N
Algorithm for Predictive Parsing:
Construct a transition diagram (DFA/NFA) for each rule of the grammar.
Optimize the DFA by reducing the number of states.
Simulate the input string on the transition diagram to parse it.
If the transition diagram reaches an accept state after consuming the entire input, the string is
successfully parsed.
Program:
#include <stdio.h>
#include <string.h>
char prol[7][10] = { "S", "A", "A", "B", "B", "C", "C" };
char pror[7][10] = { "A", "Bb", "Cd", "aB", "@", "Cc", "@" };
char prod[7][10] = { "S->A", "A->Bb", "A->Cd", "B->aB", "B->@", "C->Cc", "C->@" };
char first[7][10] = { "abcd", "ab", "cd", "a@", "@", "c@", "@" };
char follow[7][10] = { "$", "$", "$", "a$", "b$", "c$", "d$" };
char table[5][6][10];
int numr(char c)
switch (c)
case 'S':
return 0;
case 'A':
return 1;
case 'B':
return 2;
case 'C':
return 3;
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 42
Subject Name -Compiler Design Subject Code- BTCS601N
case 'a':
return 0;
case 'b':
return 1;
case 'c':
return 2;
case 'd':
return 3;
case '$':
return 4;
return (2);
int main()
int i, j, k;
for (i = 0; i < 5; i++)
for (j = 0; j < 6; j++)
strcpy(table[i][j], " ");
printf("The following grammar is used for Parsing Table:\n");
for (i = 0; i < 7; i++)
printf("%s\n", prod[i]);
printf("\nPredictive parsing table:\n");
fflush(stdin);
for (i = 0; i < 7; i++)
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 43
Subject Name -Compiler Design Subject Code- BTCS601N
k = strlen(first[i]);
for (j = 0; j < 10; j++)
if (first[i][j] != '@')
strcpy(table[numr(prol[i][0]) + 1][numr(first[i][j]) + 1], prod[i]);
for (i = 0; i < 7; i++)
if (strlen(pror[i]) == 1)
if (pror[i][0] == '@')
k = strlen(follow[i]);
for (j = 0; j < k; j++)
strcpy(table[numr(prol[i][0]) + 1][numr(follow[i][j]) + 1], prod[i]);
strcpy(table[0][0], " ");
strcpy(table[0][1], "a");
strcpy(table[0][2], "b");
strcpy(table[0][3], "c");
strcpy(table[0][4], "d");
strcpy(table[0][5], "$");
strcpy(table[1][0], "S");
strcpy(table[2][0], "A");
strcpy(table[3][0], "B");
strcpy(table[4][0], "C");
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 44
Subject Name -Compiler Design Subject Code- BTCS601N
printf("\n--------------------------------------------------------\n");
for (i = 0; i < 5; i++)
for (j = 0; j < 6; j++)
printf("%-10s", table[i][j]);
if (j == 5)
printf("\n--------------------------------------------------------\n");
Output:
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 45
Subject Name -Compiler Design Subject Code- BTCS601N
Experiment-11
Aim:- WAP to design LALR(1) Parser for any Grammar.
Descritpion:
LALR Parser is Look Ahead LR Parser. It is intermediate in power between SLR and CLR
parser. It is the compaction of CLR Parser, and hence tables obtained in this will be smaller
than CLR Parsing Table.
Here, first of all, we will construct LR (1) items. Next, we will look for the items having the
same first component, and they are merged to form a single set of items. It means the states
have the same first component, but the different second component can be integrated into a
single state or item.
For Example.
Suppose if
I4: C → d ∙ , c | d
I7: C → d ∙ , $
Both items or states (I4 and I7) have the same first component, i.e., d ∙ , but a different second
component, i.e., c | d in I4 and $ in I7.
∴ these states can be merged to give
I47: C → d ∙ , c |d | $
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 46
Subject Name -Compiler Design Subject Code- BTCS601N
Algorithm
Input − Augmented Grammar G′
Output − LALR Parsing Table
Method
• Construct LR (1) set of items, i.e., construct
C = {I0, I1, I2 … . . In}
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 47
Subject Name -Compiler Design Subject Code- BTCS601N
• Select the similar states having the same core, or first component and merge them into
one.
Let C′ = {J0, J1, J2 … . . Jm} be the resulting set.
• Construct Parsing Action for state J1 similar to CLR construction. If there is a conflict
in the Parsing Table, the algorithm can be considered to fail to produce an LALR parser.
• Construct goto actions as below.
Let goto [J,∗] = K where J is the union of one or more states of C.
i.e., J = I1 ∪ I2 … .∪ Im, then
then K = goto (I1,∗) ∪ goto (I2,∗) … .∪ goto (Im,∗)
Program:
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
void push(char *, int *, char);
char stacktop(char *);
void isproduct(char, char);
int ister(char);
int isnter(char);
int isstate(char);
void error();
void isreduce(char, char);
char pop(char *, int *);
void printt(char *, int *, char[], int);
void rep(char[], int);
struct action
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 48
Subject Name -Compiler Design Subject Code- BTCS601N
char row[6][5];
};
const struct action A[12] = {
{"sf", "emp", "emp", "se", "emp", "emp"},
{"emp", "sg", "emp", "emp", "emp", "acc"},
{"emp", "rc", "sh", "emp", "rc", "rc"},
{"emp", "re", "re", "emp", "re", "re"},
{"sf", "emp", "emp", "se", "emp", "emp"},
{"emp", "rg", "rg", "emp", "rg", "rg"},
{"sf", "emp", "emp", "se", "emp", "emp"},
{"sf", "emp", "emp", "se", "emp", "emp"},
{"emp", "sg", "emp", "emp", "sl", "emp"},
{"emp", "rb", "sh", "emp", "rb", "rb"},
{"emp", "rb", "rd", "emp", "rd", "rd"},
{"emp", "rf", "rf", "emp", "rf", "rf"}
};
struct gotol
char r[3][4];
};
const struct gotol G[12] = {
{"b", "c", "d"},
{"emp", "emp", "emp"},
{"emp", "emp", "emp"},
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 49
Subject Name -Compiler Design Subject Code- BTCS601N
{"emp", "emp", "emp"},
{"i", "c", "d"},
{"emp", "emp", "emp"},
{"emp", "j", "d"},
{"emp", "emp", "k"},
{"emp", "emp", "emp"},
{"emp", "emp", "emp"},
};
char ter[6] = {'i', '+', '*', ')', '(', '$'};
char nter[3] = {'E', 'T', 'F'};
char states[12] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'm', 'j', 'k', 'l'};
char stack[100];
int top = -1; char temp[10];
struct grammar
char left;
char right[5];
};
const struct grammar rl[6] = {
{'E', "e+T"},
{'E', "T"},
{'T', "T*F"},
{'T', "F"},
{'F', "(E)"},
{'F', "i"},
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 50
Subject Name -Compiler Design Subject Code- BTCS601N
};
int main()
char inp[80], x, p, dl[80], y, bl = 'a';
int i = 0, j, k, l, n, m, c, len;
printf(" Enter the input :");
scanf("%s", inp);
len = strlen(inp); inp[len] = '$';
inp[len + 1] = '\0';
push(stack, &top, bl);
printf("\n stack \t\t\t input");
printf(stack, &top, inp, i);
do
x = inp[i];
p = stacktop(stack);
isproduct(x, p);
if (strcmp(temp, "emp") == 0)
error();
if (strcmp(temp, "acc") == 0)
break;
else
if (temp[0] == 's')
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 51
Subject Name -Compiler Design Subject Code- BTCS601N
push(stack, &top, inp[i]);
push(stack, &top, temp[1]);
i++;
else
if (temp[0] == 'r')
j = isstate(temp[1]);
strcpy(temp, rl[j - 2].right);
dl[0] = rl[j - 2].left;
dl[1] = '\0';
n = strlen(temp);
for (k = 0; k < 2 * n; k++)
pop(stack, &top);
for (m = 0; dl[m] != '\0'; m++)
push(stack, &top, dl[m]);
l = top;
y = stack[l - 1];
isreduce(y, dl[0]);
for (m = 0; temp[m] != '\0'; m++)
push(stack, &top, temp[m]);
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 52
Subject Name -Compiler Design Subject Code- BTCS601N
printt(stack, &top, inp, i);
} while (inp[i] != '\0');
if (strcmp(temp, "acc") == 0)
printf(" \n accept the input ");
else
printf(" \n do not accept the input ");
getch();
void push(char *s, int *sp, char item)
if (*sp == 100)
printf(" stack is full ");
else
*sp = *sp + 1;
s[*sp] = item;
char stacktop(char *s)
char i;
i = s[top];
return i;
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 53
Subject Name -Compiler Design Subject Code- BTCS601N
void isproduct(char x, char p)
int k, l;
k = ister(x);
l = isstate(p);
strcpy(temp, A[l - 1].row[k - 1]);
int ister(char x)
int i;
for (i = 0; i < 6; i++)
if (x == ter[i])
return i + 1;
return 0;
int isnter(char x)
int i;
for (i = 0; i < 3; i++)
if (x == nter[i])
return i + 1;
return 0;
int isstate(char p)
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 54
Subject Name -Compiler Design Subject Code- BTCS601N
int i;
for (i = 0; i < 12; i++)
if (p == states[i])
return i + 1;
return 0;
void error()
printf(" error in the input ");
exit(0);
void isreduce(char x, char p)
int k, l;
k = isstate(x);
l = isnter(p);
strcpy(temp, G[k - 1].r[l - 1]);
char pop(char *s, int *sp)
char item;
if (*sp == -1)
printf(" stack is empty ");
else
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 55
Subject Name -Compiler Design Subject Code- BTCS601N
item = s[*sp];
*sp = *sp - 1;
return item;
void printt(char *t, int *p, char inp[], int i)
int r; printf("\n");
for (r = 0; r <= *p; r++)
rep(t, r);
printf("\t\t\t");
for (r = i; inp[r] != '\0'; r++)
printf("%c", inp[r]);
void rep(char t[], int r)
char c; c = t[r];
switch (c)
case 'a':
printf("0");
break;
case 'b':
printf("1");
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 56
Subject Name -Compiler Design Subject Code- BTCS601N
break;
case 'c':
printf("2");
break;
case 'd':
printf("3");
break;
case 'e':
printf("4");
break;
case 'f':
printf("5");
break;
case 'g':
printf("6");
break;
case 'h':
printf("7");
break;
case 'm':
printf("8");
break;
case 'j':
printf("9");
break;
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 57
Subject Name -Compiler Design Subject Code- BTCS601N
case 'k':
printf("10");
break;
case 'l':
printf("11");
break;
default:
printf("%c", t[r]);
break;
Output:
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 58
Subject Name -Compiler Design Subject Code- BTCS601N
Experiment-12
Aim: - WAP to generate machine code from the abstract Syntax Tree
generated by the parser.
Description:
a parse tree is generated by the parser, which is a component of the compiler that processes
the source code and checks it for syntactic correctness. The parse tree is then used by other
components of the compiler, such as the code generator, to generate machine code or
intermediate code that can be executed by the target machine.
Parse trees can be represented in different ways, such as a tree structure with nodes
representing the different elements in the source code and edges representing the relationships
between them, or as a graph with nodes and edges representing the same information. Parse
trees are typically used as an intermediate representation in the compilation process, and are
not usually intended to be read by humans.
A syntax tree is a tree-like representation of the syntactic structure of a piece of source code.
It is typically used in the process of compiler design, to represent the structure of the code in
a way that is easier to analyze and manipulate.
Syntax trees are constructed by parsing the source code, which involves analyzing the code
and breaking it down into its individual components, such as tokens, variables, and statements.
The resulting tree is made up of nodes that correspond to these various components, with the
structure of the tree reflecting the grammatical structure of the source code.
Syntax trees are useful for a variety of tasks in compiler design, such as type checking,
optimization, and code generation. They can also be used to represent the structure of other
types of linguistic or logical structures, such as natural language sentences or logical
expressions.
Algorihtm:
function generateMachineCode(node):
if node is null:
return
// Visit each node in the AST
switch (node.type):
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 59
Subject Name -Compiler Design Subject Code- BTCS601N
case ExpressionNode:
// Generate code for expression evaluation
generateExpressionCode(node)
case StatementNode:
// Generate code for statement execution
generateStatementCode(node)
case FunctionCallNode:
// Generate code for function call
generateFunctionCallCode(node)
// Add cases for other node types as needed
function generateExpressionCode(expressionNode):
switch (expressionNode.operator):
case ADD:
// Generate code to add operands
generateExpressionCode(expressionNode.leftOperand)
generateExpressionCode(expressionNode.rightOperand)
emitMachineCode(ADD_INSTRUCTION)
// Add cases for other operators (subtract, multiply, divide, etc.)
function generateStatementCode(statementNode):
switch (statementNode.type):
case AssignmentStatement:
// Generate code for assignment
generateExpressionCode(statementNode.expression)
storeResultInMemory(statementNode.variable)
case IfStatement:
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 60
Subject Name -Compiler Design Subject Code- BTCS601N
// Generate code for if-else statement
generateExpressionCode(statementNode.condition)
emitMachineCode(BRANCH_IF_FALSE_INSTRUCTION, label_for_else)
generateStatementCode(statementNode.ifBranch)
emitMachineCode(BRANCH_INSTRUCTION, label_for_end)
emitLabel(label_for_else)
generateStatementCode(statementNode.elseBranch)
emitLabel(label_for_end)
// Add cases for other types of statements
function generateFunctionCallCode(callNode):
// Generate code to push arguments onto stack
for argument in callNode.arguments:
generateExpressionCode(argument)
pushArgumentToStack(argument.value)
// Generate code to call function and handle return value
emitMachineCode(CALL_FUNCTION_INSTRUCTION, callNode.functionName)
handleReturnValue(callNode.functionName)
Program:
#include <stdio.h>
#include <stdlib.h>
// Define the types of AST nodes
typedef enum {
NODE_ADD,
NODE_SUBTRACT,
NODE_MULTIPLY,
NODE_DIVIDE,
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 61
Subject Name -Compiler Design Subject Code- BTCS601N
NODE_NUMBER
} NodeType;
// Define the structure of an AST node
typedef struct ast_node {
NodeType type;
int value; // For NODE_NUMBER type
struct ast_node *left;
struct ast_node *right;
} ASTNode;
// Function to generate machine code from AST
void generate_machine_code(ASTNode *node) {
if (node == NULL)
return;
switch (node->type) {
case NODE_ADD:
generate_machine_code(node->left);
generate_machine_code(node->right);
printf("ADD\n");
break;
case NODE_SUBTRACT:
generate_machine_code(node->left);
generate_machine_code(node->right);
printf("SUBTRACT\n");
break;
case NODE_MULTIPLY:
generate_machine_code(node->left);
generate_machine_code(node->right);
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 62
Subject Name -Compiler Design Subject Code- BTCS601N
printf("MULTIPLY\n");
break;
case NODE_DIVIDE:
generate_machine_code(node->left);
generate_machine_code(node->right);
printf("DIVIDE\n");
break;
case NODE_NUMBER:
printf("LOAD %d\n", node->value);
break;
default:
printf("Unknown node type\n");
// Example usage
int main() {
// Example AST: 5 + 4 * 3
ASTNode *root = (ASTNode *)malloc(sizeof(ASTNode));
root->type = NODE_ADD;
root->left = (ASTNode *)malloc(sizeof(ASTNode));
root->left->type = NODE_NUMBER;
root->left->value = 5;
root->left->left = NULL;
root->left->right = NULL;
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 63
Subject Name -Compiler Design Subject Code- BTCS601N
root->right = (ASTNode *)malloc(sizeof(ASTNode));
root->right->type = NODE_MULTIPLY;
root->right->left = (ASTNode *)malloc(sizeof(ASTNode));
root->right->left->type = NODE_NUMBER;
root->right->left->value = 4;
root->right->left->left = NULL;
root->right->left->right = NULL;
root->right->right = (ASTNode *)malloc(sizeof(ASTNode));
root->right->right->type = NODE_NUMBER;
root->right->right->value = 3;
root->right->right->left = NULL;
root->right->right->right = NULL;
// Generate machine code
generate_machine_code(root);
// Clean up memory
free(root->right->right);
free(root->right->left);
free(root->right);
free(root->left);
free(root);
return 0;
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 64
Subject Name -Compiler Design Subject Code- BTCS601N
Output:
Name – Tarishi chouhan Enrollment no.-21100BTAIMLM09381 III YEAR/VISEM 65