CD Practical File
CD Practical File
PRACTICAL FILE
10
11
EXPERIMENT-01
Aim:
Practice of LEX/YACC of Compiler design.
Theory:
1) LEX (Lexical Analyzer Generator)
Purpose:
LEX is a lexical analyzer generator that takes a specification of tokens (patterns of
characters, like keywords, operators, identifiers, etc.) and generates a lexical
analyzer (or scanner). The lexical analyzer reads the input, identifies tokens, and
passes them to the parser (generated by YACC).
Advantages of LEX:
• Automated Lexical Analysis: It simplifies the process of tokenizing input by
using regular expressions to automatically generate C code for token
recognition.
• Efficiency: LEX-generated scanners are highly efficient and fast.
2) YACC (Yet Another Compiler-Compiler)
Purpose:
YACC is a parser generator that reads a formal grammar specification and
generates C code for a parser. The parser processes tokens (provided by the lexical
analyzer) and constructs the syntactic structure of the input (typically in the form of
a parse tree or abstract syntax tree).
Advantages of YACC:
• Automated Parser Generation: YACC automates the process of writing
parsers, making it easier to design complex grammars.
• Error Detection: YACC can handle syntax errors efficiently by reporting
errors when tokens do not match grammar rules.
EXPERIMENT-02
Aim:
Write a program to check whether a string include keyword or not.
Code:
#include<iostream>
#include<string>
int main() {
std::string str, keyword;
std::cout << "Enter a string: ";
std::getline(std::cin, str);
std::cout << "Enter a keyword: ";
std::getline(std::cin, keyword);
if (str.find(keyword) != std::string::npos) {
std::cout << "The keyword is present in the string." << std::endl;
} else {
std::cout << "The keyword is not present in the string." << std::endl;
}
return 0;
}
Output:
EXPERIMENT-03
Aim:
Write a program to check whether a string contains an alphabet or not.
Code:
#include <iostream>
#include <string>
#include <cctype> // For isalpha function
int main() {
std::string str;
bool hasAlphabet = false;
if (hasAlphabet) {
std::cout << "The string contains at least one alphabet character." << std::endl;
} else {
std::cout << "The string does not contain any alphabet characters." <<
std::endl;
}
return 0;
}
Output:
EXPERIMENT-04
Aim:
Write a program to show all the operations of a stack.
Code:
#include <iostream>
#include <stack>
int main() {
std::stack<int> stack;
int choice, value;
do {
std::cout << "\nStack Operations Menu:";
std::cout << "\n1. Push";
std::cout << "\n2. Pop";
std::cout << "\n3. Top";
std::cout << "\n4. Is Empty";
std::cout << "\n5. Size";
std::cout << "\n6. Exit";
std::cout << "\nEnter your choice: ";
std::cin >> choice;
switch (choice) {
case 1:
std::cout << "Enter value to push: ";
std::cin >> value;
stack.push(value);
std::cout << value << " pushed into the stack." << std::endl;
break;
case 2:
if (!stack.empty()) {
std::cout << "Popped value: " << stack.top() << std::endl;
stack.pop();
} else {
std::cout << "Stack is empty." << std::endl;
}
break;
case 3:
if (!stack.empty()) {
std::cout << "Top value: " << stack.top() << std::endl;
} else {
std::cout << "Stack is empty." << std::endl;
}
break;
case 4:
if (stack.empty()) {
std::cout << "Stack is empty." << std::endl;
} else {
std::cout << "Stack is not empty." << std::endl;
}
break;
case 5:
std::cout << "Stack size: " << stack.size() << std::endl;
break;
case 6:
std::cout << "Exiting..." << std::endl;
break;
default:
std::cout << "Invalid choice. Please try again." << std::endl;
break;
}
} while (choice != 6);
return 0;
}
Output:
EXPERIMENT-05
Aim:
Write a program to remove left recursion from a grammar.
Code:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main(){
vector<Production> productions={
{'E',{"E+T","T"}},
{'T',{"T*F","F"}},
{'F',{"(E)","id"}}
};
vector<Production> newProductions=removeLeftRecursion(productions);
cout<<"Original Productions:"<<endl;
for(const Production& prod:productions){
cout<<prod.nonTerminal<<".>";
for(const string& symbol:prod.symbols){
cout<<symbol<<"|";
}
cout<<endl;
}