cd final file
cd final file
OUTPUT:
PROGRAM-3
Aim - Write a program to convert INFIX notation to POSTFIX
and PREFIX notation.
#include <iostream>
#include <stack>
#include <algorithm>
using namespace std;
// Function to check if the given character is an operator
bool isOperator(char c) {
return (c == '+' || c == '-' || c == '*' || c == '/' || c == '^');
}
// Function to check the precedence of operators
int precedence(char c) {
if (c == '^')
return 3;
else if (c == '*' || c == '/')
return 2;
else if (c == '+' || c == '-')
return 1;
else
return -1;
}
// Function to convert infix to postfix
string infixToPostfix(string infix) {
stack<char> s;
string postfix = "";
for (int i = 0; i < infix.length(); i++) {
char c = infix[i];
// If character is an operand, add it to the result
if (isalnum(c)) {
postfix += c;
}
// If character is '(', push it to the stack
else if (c == '(') {
s.push(c);
}
// If character is ')', pop and output from the stack
// until an '(' is encountered
else if (c == ')') {
while (!s.empty() && s.top() != '(') {
postfix += s.top();
s.pop();
}
s.pop(); // Remove '(' from stack
}
// If an operator is encountered
else if (isOperator(c)) {
while (!s.empty() && precedence(s.top()) >= precedence(c)) {
postfix += s.top();
s.pop();
}
s.push(c);
}
}
// Pop all the operators from the stack
while (!s.empty()) {
postfix += s.top();
s.pop();
}
return postfix;
}
// Function to convert infix to prefix
string infixToPrefix(string infix) {
// Reverse the infix expression
reverse(infix.begin(), infix.end());
// Replace '(' with ')' and vice versa
for (int i = 0; i < infix.length(); i++) {\
if (infix[i] == '(') {
infix[i] = ')';
}
else if (infix[i] == ')') {
infix[i] = '(';
}
}
// Get the postfix of the modified expression
string postfix = infixToPostfix(infix);
// Reverse the postfix to get prefix
reverse(postfix.begin(), postfix.end());
return postfix;
}
int main() {
string infix;
cout << "Enter an infix expression: ";
cin >> infix;
string postfix = infixToPostfix(infix);
string prefix = infixToPrefix(infix);
cout << "Postfix expression: " << postfix << endl;
cout << "Prefix expression: " << prefix << endl;
return;
}
OUTPUT:
PROGRAM-4
Aim - Write a program in C++ to find the first and follow of the
non-terminal string in Grammar.
#include <iostream>
#include <vector>
#include <set>
#include <map>
#include <string>
class Grammar {
public:
map<char, vector<string>> productions;
map<char, set<char>> first;
map<char, set<char>> follow;
void computeFirst();
void computeFollow();
void displayFirst();
void displayFollow();
void getInput();
};
void Grammar::computeFirst() {
for (const auto& pair : productions) {
char nonTerminal = pair.first;
for (const string& production : pair.second) {
if (isupper(production[0])) { // Non-terminal
first[nonTerminal].insert(first[production[0]].begin(), first[production[0]].end());
} else { // Terminal
first[nonTerminal].insert(production[0]);
}
}
}
}
void Grammar::computeFollow() {
char startSymbol = productions.begin()->first;
follow[startSymbol].insert('$'); // End marker for start symbol
void Grammar::displayFirst() {
cout << "First Sets:\n";
for (const auto& pair : first) {
cout << "First(" << pair.first << ") = { ";
for (char c : pair.second) {
cout << c << " ";
}
cout << "}\n";
}
}
void Grammar::displayFollow() {
cout << "Follow Sets:\n";
for (const auto& pair : follow) {
cout << "Follow(" << pair.first << ") = { ";
for (char c : pair.second) {
cout << c << " ";
}
cout << "}\n";
}
}
void Grammar::getInput() {
int numProductions;
cout << "Enter number of productions: ";
cin >> numProductions;
cin.ignore(); // To ignore the newline character after number input
int main() {
Grammar grammar;
return 0;
}
OUTPUT:
PROGRAM-5
Aim- Write a program to check whether a string is an identifier
or not.
#include <iostream>
#include <string>
#include <cctype>
using namespace std;
bool isValidIdentifier(const string& str) {
if (str.empty() || isdigit(str[0])) {
return false;
}
for (char c : str) {
if (!isalnum(c) && c != '_') {
return false;
}
}
return true;
}
int main() {
string input;
cout << "Enter a string to check if it's a valid identifier: ";
cin >> input;
if (isValidIdentifier(input)) {
cout << "'" << input << "' is a valid identifier." << endl;
} else {
cout << "'" << input << "' is not a valid identifier." << endl;
}
return 0;
}
OUTPUT:
PROGRAM-6
Aim- Write a program to check whether a string belongs to
grammar or not.
#include <iostream>
#include <map>
#include <vector>
using namespace std;
map<char, vector<string>> grammar;
bool isValid(string input, char start)
{
if (input.empty()) return false;
vector<string> productions = grammar[start];
for (string prod : productions)
{
if (input == prod)
{
return true;
}
}
return false;
}
int main()
{
int n;
cout << "Enter number of productions: ";
cin >> n;
cout << "Enter productions (e.g., A->a):\n";
for (int i = 0; i < n; i++)
{
char nonTerminal;
string arrow, production;
cin >> nonTerminal >> arrow >> production;
grammar[nonTerminal].push_back(production);
}
char start;
cout << "Enter start symbol: ";
cin >> start;
string input;
cout << "Enter string to check: ";
cin >> input;
if (isValid(input, start))
{
cout << "The string belongs to the grammar.\n";
}
else
{
cout << "The string does NOT belong to the grammar.\n";
}
return 0;
}
OUTPUT:
PROGRAM-7
Aim- Write a program to remove left recursion from a
grammar.
#include <iostream>
#include <vector>
#include <map>
#include <string>
#include <algorithm>
using namespace std;
map<char, vector<string>> grammar;
void removeLeftRecursion()
{
for (auto& entry : grammar)
{
char A = entry.first;
vector<string> alpha, beta;
for (const string& production : entry.second)
{
if (production[0] == A)
{
alpha.push_back(production.substr(1));
}
else
{
beta.push_back(production);
}
}
if (!alpha.empty())
{
char newNonTerminal = A + 1;
while (grammar.find(newNonTerminal) != grammar.end())
{
newNonTerminal++;
}
grammar[A].clear();
for (const string& b : beta)
{
grammar[A].push_back(b + newNonTerminal);
}
grammar[newNonTerminal] = vector<string>();
for (const string& a : alpha)
{
grammar[newNonTerminal].push_back(a + newNonTerminal);
}
grammar[newNonTerminal].push_back("ε");
}
}
}
int main()
{
int numProductions;
cout << "Enter the number of productions: ";
cin >> numProductions;
cin.ignore();
cout << "Enter the productions in the format 'S->aA|b':" << endl;
for (int i = 0; i < numProductions; i++)
{
string production;
getline(cin, production);
char nonTerminal = production[0];
string rhs = production.substr(3);
size_t pos = 0;
while ((pos = rhs.find('|')) != string::npos)
{
grammar[nonTerminal].push_back(rhs.substr(0, pos));
rhs.erase(0, pos + 1);
}
grammar[nonTerminal].push_back(rhs);
}
cout << "\nOriginal Grammar:" << endl;
for (const auto& entry : grammar)
{
cout << entry.first << " -> ";
for (size_t i = 0; i < entry.second.size(); i++)
{
cout << entry.second[i];
if (i < entry.second.size() - 1) cout << " | ";
}
cout << endl;
}
removeLeftRecursion();
cout << "\nGrammar after removing left recursion:" << endl;
for (const auto& entry : grammar)
{
cout << entry.first << " -> ";
for (size_t i = 0; i < entry.second.size(); i++)
{
cout << entry.second[i];
if (i < entry.second.size() - 1) cout << " | ";
}
cout << endl;
}
return 0;
}
OUTPUT:
PROGRAM-8
Aim- Write a program to remove left factoring from a grammar
#include <iostream>
#include <vector>
#include <string>
using namespace std;
void removeLeftFactoring(string nonTerminal, vector<string>
productions)
{
string prefix = productions[0];
for (string prod : productions)
{
int j = 0;
while (j < prefix.length() && j < prod.length() && prefix[j]
== prod[j])
{
j++;
}
prefix = prefix.substr(0, j);
}
if (prefix.empty())
{
cout << "No left factoring found.\n";
return;
}
cout << nonTerminal << " -> " << prefix << nonTerminal << "'\n";
cout << nonTerminal << "' -> ";
for (string prod : productions)
{
if (prod != prefix)
{
cout << prod.substr(prefix.length()) << " | ";
}
}
cout << "ε\n";
}
int main()
{
int n;
cout << "Enter the number of productions: ";
cin >> n;
string nonTerminal;
cout << "Enter the non-terminal: ";
cin >> nonTerminal;
vector<string> productions(n);
cout << "Enter the productions:\n";
for (int i = 0; i < n; i++)
{
cin >> productions[i];
}
removeLeftFactoring(nonTerminal, productions);
return 0;
}
OUTPUT:
PROGRAM-9
Aim- Write a program to generate SDT for a given graph.
#include <iostream>
#include <vector>
using namespace std;
return graph;
}
// Since the graph is undirected, add an edge from dest to src as well
newNode = newAdjListNode(src);
newNode->next = graph->arr[dest].head;
graph->arr[dest].head = newNode;
}
// Function to print the adjacency list representation of the graph
void printGraph(Graph* graph) {
for (int i = 0; i < graph->V; i++) {
AdjListNode* root = graph->arr[i].head;
cout << "Adjacency list of vertex " << i << ": ";
while (root != nullptr) {
cout << root->data << " -> ";
root = root->next;
}
cout << "nullptr" << endl; // Indicate end of the list
}
}
int main() {
// Create a new graph with a specified number of vertices
int totalVertices = 10; // Change this value as needed
Graph* graph = createGraph(totalVertices);
return 0;
}
OUTPUT:
PROGRAM-10
Aim- Write a program to generate a parse tree.
#include <iostream>
#include <sstream>
#include <vector>
#include <stack>
#include <string>
int main() {
string expression = "( ( 10 + 5 ) * 3 )";
return 0;
}
OUTPUT:
PROGRAM-11
Aim- Write a program to show all the operations of a stack.
#include <iostream>
using namespace std;
class Stack {
private:
int arr[MAX]; // Array to store stack elements
int top; // Index of the top element
public:
Stack() { top = -1; } // Constructor to initialize the stack
int main() {
Stack s; // Create a Stack object
s.push(10);
s.push(20);
s.push(30);
cout << "Top element is: " << s.peek() << endl;
cout << s.pop() << " popped from stack." << endl;
cout << "Top element is: " << s.peek() << endl;
s.push(40);
while (!s.isEmpty()) {
cout << s.pop() << " popped from stack." << endl;
}
s.display(); // Display current stack after popping all elements
return 0;
}
OUTPUT:
PROGRAM-12
Aim- Write a program to draw the dependency graph.
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
class DependencyGraph {
private:
vector<string> nodes; // List of nodes
vector<pair<string, string>> edges; // List of edges (dependencies)
public:
// Function to add a node to the graph
void addNode(const string& node) {
nodes.push_back(node);
}
int main() {
DependencyGraph graph;
// Adding nodes
graph.addNode("A");
graph.addNode("B");
graph.addNode("C");
graph.addNode("D");
cout << "You can visualize the graph using Graphviz with the following command:" <<
endl;
cout << "dot -Tpng dependency_graph.dot -o dependency_graph.png" << endl;
return 0;
}
OUTPUT:
PROGRAM-13
Aim- Write a program to draw the DAG.
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
class DAG {
private:
vector<string> nodes; // List of nodes
vector<pair<string, string>> edges; // List of edges (dependencies)
public:
// Function to add a node to the graph
void addNode(const string& node) {
nodes.push_back(node);
}
int main() {
DAG dag;
// Adding nodes
dag.addNode("A");
dag.addNode("B");
dag.addNode("C");
dag.addNode("D");
cout << "You can visualize the graph using Graphviz with the following command:" <<
endl;
cout << "dot -Tpng dag.dot -o dag.png" << endl;
return 0;
}
OUTPUT:
PROGRAM-14
Aim- Write a program to show the symbol table enteries.
#include <iostream>
#include <string>
#include <vector>
struct Symbol {
string name; // Identifier name
string type; // Type of the identifier (e.g., int, float)
string scope; // Scope of the identifier (e.g., local, global)
int lineNo; // Line number where the identifier is declared
class SymbolTable {
private:
vector<Symbol> symbols; // Vector to store symbols
public:
// Function to insert a new symbol into the symbol table
void insert(const string& name, const string& type, const string& scope, int lineNo) {
symbols.push_back(Symbol(name, type, scope, lineNo));
cout << "Inserted: " << name << " (Type: " << type << ", Scope: " << scope << ", Line: "
<< lineNo << ")" << endl;
}
int main() {
SymbolTable st;
return 0;
}
OUTPUT: