CD 1 to 11 Practical
CD 1 to 11 Practical
Code:
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
return (false);
'=')
return (true);
return (false);
(false);
return (true);
!strcmp(str, "break") ||
(true);
return (false);
(len == 0)
return (false);
for (i = 0; i < len; i++) {
if (str[i] != '0' && str[i] != '1' && str[i] != '2'
return (false);
return (true);
0)
return (false);
(false);
= true;
return (hasDecimal);
}
char* subString(char* str, int left, int right)
{
int i;
return (subStr);
len = strlen(str);
(isDelimiter(str[right]) == false)
right++;
(isOperator(str[right]) == true)
right++;
left = right;
(isKeyword(subStr) == true)
printf("'%s' IS A KEYWORD\n", subStr); else if
(isInteger(subStr) == true)
= right;
return;
int main()
parse(str);
return (0);
Output :
PRACTICAL - 02
Output:
PRACTICAL - 03
Output:
File: program.c
PRACTICAL - 09
Output :
(ii)
%{
#include <stdio.h>
%}
%%
[0-9]+ { printf("Saw an integer: %s\n", yytext); }
.{;}
%%
int main(){
printf("Enter some input that consists of an integer number\n");
yylex(); }
int
yywrap(){
return 1;
}
Output:
PRACTICAL - 10
bool flag = 0;
cout<<"Grammar: "<<'\n';
while(getline(fin,num)){
if(flag == 0) start = num[0],flag = 1;
cout<<num<<'\n';
vector<char> temp;
char s = num[0];
for(i=3;i<num.size();i++){
if(num[i] ==
'|'){ mp[s].push_back(temp)
; temp.clear();}
else temp.push_back(num[i]); }
mp[s].push_back(temp); }
int flag2 = 0;
vector<char> del;
map<char,vector<vector<char>>> add;
vector<int> viz(100,0);
for(auto q :
mp){ int one
= 0; char c;
for(auto r :
q.second){ if(q.first
== r[0]){
one = 1;
flag2 = 1;
del.push_back(q.first);
c = 'A';
while(mp.count(c)||viz[c-'A']) c++;
vector<char> temp;
for(i=1;i<r.size();i++)
temp.push_back(r[i]);
temp.push_back(c);
add[c].push_back(temp);
add[c].push_back({'e'});}}
if(one){
for(auto r :
q.second){ if(q.first
!= r[0]){
vector<char> temp;
for(i=0;i<r.size();i++)
temp.push_back(r[i]);
temp.push_back(c);
add[q.first].push_back(temp); }}
viz[c-'A'] = 1; }}
for(auto q : del) mp.erase(q);
for(auto q : add) mp[q.first] = q.second;
if(flag2){
cout<<"\nGiven CFG is not suitable for LL1\nConverting...\n"<<'\n';
cout<<"New Grammar:"<<'\n';
for(auto q :
mp){ string
ans = "";
ans+=q.first;
ans += "->";
for(auto r :
q.second){ for(auto s : r)
ans+=s; ans+='|'; }
ans.pop_back();
cout<<ans<<'\n'; }}
else cout<<"\nGiven CFG is not suitable for LL1"<<'\n';
map<char,set<char>> fmp;
for(auto q :
mp){ ss.clear();
dfs(q.first,q.first,q.first,mp);
for(auto g : ss) fmp[q.first].insert(g); }
cout<<'\n';
cout<<"FIRST: "<<'\n';
for(auto q :
fmp){ string ans
= ""; ans +=
q.first; ans += "
= {";
for(char r :
q.second){ ans += r;
ans += ','; }
ans.pop_back();
ans+="}";
cout<<ans<<'\n'; }
map<char,set<char>> gmp;
gmp[start].insert('$');
int count = 10;
while(count--
){
for(auto q :
mp){ for(auto r :
q.second){
for(i=0;i<r.size()-1;i++){
if(r[i]>='A'&&r[i]<='Z'){
if(!(r[i+1]>='A'&&r[i+1]<='Z')) gmp[r[i]].insert(r[i+1]);
else {
char temp = r[i+1];
int j = i+1;
while(temp>='A'&&temp<='Z'){ if(*fmp[temp].begin()
=='e'){
for(auto g :
fmp[temp]){ if(g=='e')
continue;
gmp[r[i]].insert(g); }
j++;
if(j<r.size()){ t
emp = r[j];
if(!(temp>='A'&&temp<='Z')){
gmp[r[i]].insert(temp);
break; }}
else{
for(auto g : gmp[q.first]) gmp[r[i]].insert(g);
break; }}
else{
for(auto g : fmp[temp]){
gmp[r[i]].insert(g); }
break; }}}}}
if(r[r.size()-1]>='A'&&r[r.size()-1]<='Z'){
for(auto g : gmp[q.first]) gmp[r[i]].insert(g); }}}}
cout<<'\n';
cout<<"FOLLOW: "<<'\n';
for(auto q :
gmp){ string
ans = ""; ans +=
q.first; ans += "
= {";
for(char r :
q.second){ ans += r;
ans += ','; }
ans.pop_back();
ans+="}";
cout<<ans<<'\n'; }
return 0;
}
Output:
PRACTICAL - 11
switch (this-
>leaf.type){ case
Token::INTEGER:
this->type=expr; }}
void reduce_expr(){
if (!this->branches.size())
return;
if (this->branches.size()<3)
this->leaf=this->branches[0].leaf;
else{
this->leaf.type=Token::INTEGER;
switch (this-
>branches[1].leaf.type){
case Token::PLUS:
this->leaf.intValue=this->branches[0].leaf.intValue+this-
>branches[2].leaf.intValue;
break;
case Token::MINUS:
this->leaf.intValue=this->branches[0].leaf.intValue-this-
>branches[2].leaf.intValue;
break;
default:; }}
this->reduced=1;
this->branches.clear();}
public:
NonTerminal(NonTerminal
*trunk=0){ this->type=expr;
this->trunk=trunk;
this->reduced=0; }
NonTerminal(const Token &token,NonTerminal
*trunk=0){ this->leaf=token;
this->type=terminal;
this->trunk=trunk;
this->reduced=0; }
void set(const Token
&token){ this->leaf=token;
this->type=terminal;
this->trunk=trunk;
this->reduced=0; }
void push(const Token
&token){ if (this-
>type==terminal)
return;
this->branches.push_back(NonTerminal(token)); }
NonTerminal *newBranch(const Token &token){
this->branches.push_back(NonTerminal(this));
return &this->branches.back();}
bool isComplete(){
if (this->type==terminal)
return 1;
if (!this->branches.size())
return 0;
for (unsigned a=0;a<this->branches.size();a++)
if (this->branches[a].type!=terminal && !this->branches[a].reduced)
return 0;
switch (this-
>branches.size()){ case 1:
return this->branches[0].leaf.type==Token::INTEGER;
case 3:
if (this->branches[0].leaf.type!=Token::INTEGER ||
this->branches[1].leaf.type!=Token::PLUS &&
this->branches[1].leaf.type!=Token::MINUS ||
this->branches[2].leaf.type!=Token::INTEGER)
return 0;
return 1;
default:
return 0; }}
NonTerminal *reduce(){
if (!this->isComplete())
return 0;
switch (this->type){
case terminal:
this->reduce_terminal();
break;
case expr:
this->reduce_expr();
break; }
return this->trunk?this->trunk:this; }};
class Parser{
std::deque<Token> expression;
std::stack<Token> stack;
long result;
unsigned state;
NonTerminal tree,
*current_node;
Token read(std::stringstream &stream){
//(lexer) }
unsigned
run_state(){
Token::TokenType front_token_type;
switch (this->state){
case 0:
front_token_type=this->expression.front().type;
if (front_token_type==Token::INTEGER)
return 3;
if (front_token_type==Token::END)
return 1;
return 2;
case 3:
this->current_node->push(this->expression.front());
this->expression.pop_front();
if (this->current_node->isComplete())
this->current_node=this->current_node->reduce();
front_token_type=this->expression.front().type;
if (front_token_type==Token::PLUS ||
front_token_type==Token::MINUS)
return 4;
if (front_token_type==Token::END)
return 1;
return 2;
case 4:
this->current_node->push(this->expression.front());
this->expression.pop_front();
front_token_type=this->expression.front().type;
if (front_token_type==Token::INTEGER)
return 3;
return 2;
default:
return this->state; }}
//1: continue, 0: accept, -1: abort
int to_state(unsigned n){
this->state=n;
switch (n){
case 1:
return 0;
case 2:
return -1;
default:
return 1; }}
public:
Parser(const std::string
&str){ std::stringstream
stream(str); do
this->expression.push_back(this->read(stream));
while (this->expression.back().type!=Token::END);
this->result=0;
this->state=0;
this->current_node=&this->tree; }
bool eval(long &res){
int ret;
while ((ret=this->to_state(this->run_state()))==1);
if (!ret){
this->tree.reduce();
res=this->tree.leaf.intValue; }
return !ret; }};
int main(){
Parser evaluator("12+3-2");
long res;
std::cout <<evaluator.eval(res)<<std::endl;
std::cout <<res<<std::endl;
return 0;
}
Output:
PRACTICAL - 04
Output:
PRACTICAL - 05
Write a Program to check whether a given identifier is valid or not.
Code:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main() {
int t;
printf("Enter the number of test cases:\n");
scanf("%d",&t);
while(t--){
char string[50];
int count=0,i;
printf("Enter the String: ");
scanf("%s",&string);
if((string[0]>='a'&&string[0]<='z') || (string[0]>='A'&&string[0]<='Z') || (string[0]=='_')
||(string[0]=='$')){
for(i=1;i<=strlen(string);i++) {
Output:
PRACTICAL - 06
char s[20],c;
int state=0,i=0;
printf("\n Enter a string:");
scanf("%s",&s);
while(s[i]!='\0'){
switch(state){
case 0: c=s[i++];
if(c=='a') state=1;
else if(c=='b') state=2;
else
state=6; break;
case 1: c=s[i++];
if(c=='a') state=3;
else if(c=='b') state=4;
else
state=6; break;
case 2: c=s[i++];
if(c=='a') state=6;
else if(c=='b') state=2;
else state=6; break;
case 3: c=s[i++];
if(c=='a') state=3;
else if(c=='b') state=2;
else
state=6; break;
case 4: c=s[i++];
if(c=='a') state=6;
else if(c=='b')
state=5; else
state=6; break;
case 5:
c=s[i++];
if(c=='a') state=6;
else if(c=='b') state=2;
else
state=6; break;
case 6:
printf("\n %s is not recognised.",s); exit(0); } }
if(state==1)
Output:
PRACTICAL - 07
Write a Program to simulate lexical analyser for validating operators.
Code:
#include<stdio.h>
#include<conio.h>
#include<string.h>
#include<stdlib.h>
int main(){
int t;
printf("Enter the number of test cases: ");
scanf("%d",&t);
while(t--){
char s[5];
printf("\nEnter any operator: ");
scanf("%s",&s);
switch(s[0]){
case'>':
if(s[1]=='=')
printf("\n Greater than or equal"); else
printf("\n Greater than"); break;
case'<':
if(s[1]=='=')
printf("\n Less than or equal"); else
printf("\nLessthan"); break;
case'=':
if(s[1]=='=')
printf("\nEqual to"); else
printf("\nAssignment"); break;
case'!': if(s[1]=='=')
printf("\nNot Equal"); else
printf("\n Bit Not"); break;
case'&': if(s[1]=='&')
printf("\nLogical AND"); else
printf("\n Bitwise AND"); break;
case'|': if(s[1]=='|')
printf("\nLogical OR"); else
printf("\nBitwise OR"); break;
case'+':
printf("\n Addition"); break;
case'-': printf("\nSubstraction");
break;
case'*':
printf("\nMultiplication"); break;
case'/': printf("\nDivision");
break;
case'%': printf("Modulus");
break;
default: printf("\n Not an operator"); }
} getchar();
return 0;
}
Output:
PRACTICAL - 08
scanf("%d", &n);
for (i = 0; i < n; i++)
scanf("%s", grm[i]);
for (i = 0; i < n; i++) { c =
grm[i][2];
while (c != '\0') {
if (grm[i][3] == '+' || grm[i][3] == '-' || grm[i][3] == '*' || grm[i][3] == '/') flag = 1;
else {
flag = 0; f(); }
if (c == '$') { flag = 0;
f(); }
c = grm[i][++j]; } } if (flag
== 1)
printf("Operator Precedence grammar\n");
}
return 0;
}
Output: