Lab Assig 2021

You might also like

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

JINNAH UNIVERSITY FOR WOMEN

Department of Computer Science & Software Engineering


CSC 4281-Compiler Construction
LAB ASSIGNMENT
Max marks: 15
Instructions:
 The assignment must be submitted on JUW LMS.
 Email submission will not be accepted.
 Each student has to solve the assignment individually.
 Plagiarism may lead to marks deduction.
 Make your work clear and understandable.
 Submit the screen shots formatted in the word document. 
 All question carries equal mark except 12 carry 2 marks.

1a. Write a C/C++/Java/Python program which recognizes the key strokes as you press different
keys on keyboard (letters/ digits/ special characters/ white spaces).

CODE:
import java.util.Scanner;
public class AlphabetDigitSpecial {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("Enter any caracter : ");
char ch = scanner.next().charAt(0);
if((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) {
System.out.println(ch + " is A ALPHABET.");
} else if(ch >= '0' && ch <= '9') {
System.out.println(ch + " is A DIGIT.");
} else {
System.out.println(ch + " is A SPECIAL CHARACTER.");
}
}
}
OUTPUT:

1b. Write a C/C++/Java/Python program to tokenize the simple “print (4 + y *3 ) # comment”


program of C language. First of all, define the token for this program. The original program
should necessarily include few comments. Display the tokens by removing all the comments, i.e.,
the comments should be ignored for tokenization.

CODE:

#include <stdbool.h>

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

// Returns 'true' if the character is a DELIMITER. bool isDelimiter(char ch)

if (ch == ' ' || ch == '+' || ch == '-' || ch == '*' ||

ch == '/' || ch == ',' || ch == ';' || ch == '>' || ch == '<' || ch == '=' || ch == '(' || ch == ')' || ch == '[' || ch == ']' || ch ==
'{' || ch == '}') return (true);

return (false);

// Returns 'true' if the character is an OPERATOR. bool isOperator(char ch)

{
if (ch == '+' || ch == '-' || ch == '*' ||

ch == '/' || ch == '>' || ch == '<' || ch == '=')

return (true);

return (false);

// Returns 'true' if the string is a VALID IDENTIFIER. bool validIdentifier(char* str)

if (str[0] == '0' || str[0] == '1' || str[0] == '2' ||

str[0] == '3' || str[0] == '4' || str[0] == '5' ||

str[0] == '6' || str[0] == '7' || str[0] == '8' || str[0] == '9' || isDelimiter(str[0]) == true) return (false);

return (true);

// Returns 'true' if the string is a KEYWORD. bool isKeyword(char* str)

if (!strcmp(str, "if") || !strcmp(str, "else") ||

!strcmp(str, "while") || !strcmp(str, "do") ||

!strcmp(str, "break") ||

!strcmp(str, "continue") || !strcmp(str, "int")

|| !strcmp(str, "double") || !strcmp(str, "float")

|| !strcmp(str, "return") || !strcmp(str, "char")

|| !strcmp(str, "case") || !strcmp(str, "char")

|| !strcmp(str, "sizeof") || !strcmp(str, "long")

|| !strcmp(str, "short") || !strcmp(str, "typedef")

|| !strcmp(str, "switch") || !strcmp(str, "unsigned")

|| !strcmp(str, "void") || !strcmp(str, "static")

|| !strcmp(str, "struct") || !strcmp(str, "goto")) return (true);

return (false);
}

// Returns 'true' if the string is an INTEGER. bool isInteger(char* str)

int i, len = strlen(str);

if (len == 0)

return (false); for (i = 0; i < len; i++) {

if (str[i] != '0' && str[i] != '1' && str[i] != '2'

&& str[i] != '3' && str[i] != '4' && str[i] != '5'

return (true);

&& str[i] != '6' && str[i] != '7' && str[i] != '8'

&& str[i] != '9' || (str[i] == '-' && i > 0)) return (false);

// Returns 'true' if the string is a REAL NUMBER. bool isRealNumber(char* str)

int i, len = strlen(str); bool hasDecimal = false;

if (len == 0)

return (false); for (i = 0; i < len; i++) {

if (str[i] != '0' && str[i] != '1' && str[i] != '2'

&& str[i] != '3' && str[i] != '4' && str[i] != '5'

&& str[i] != '6' && str[i] != '7' && str[i] != '8'

&& str[i] != '9' && str[i] != '.' ||

(str[i] == '-' && i > 0)) return (false);

if (str[i] == '.')

hasDecimal = true;

return (hasDecimal);
}

// Extracts the SUBSTRING.

char* subString(char* str, int left, int right)

int i;

char* subStr = (char*)malloc(

sizeof(char) * (right - left + 2));

for (i = left; i <= right; i++) subStr[i - left] = str[i];

subStr[right - left + 1] = '\0'; return (subStr);

// Parsing the input STRING. void parse(char* str)

int left = 0, right = 0; int len = strlen(str);

while (right <= len && left <= right) {

if (isDelimiter(str[right]) == false) right++;

if (isDelimiter(str[right]) == true && left == right) { if (isOperator(str[right]) == true)

printf("'%c' IS AN OPERATOR\n", str[right]);

right++; left = right;

} else if (isDelimiter(str[right]) == true && left != right

|| (right == len && left != right)) { char* subStr = subString(str, left, right - 1)

if (isKeyword(subStr) == true)

printf("'%s' IS A KEYWORD\n", subStr);

else if (isInteger(subStr) == true)

printf("'%s' IS AN INTEGER\n", subStr);

else if (isRealNumber(subStr) == true)

printf("'%s' IS A REAL NUMBER\n", subStr);

else if (validIdentifier(subStr) == true


&& isDelimiter(str[right - 1]) == false) printf("'%s' IS A VALID IDENTIFIER\n", subStr);

return;

else if (validIdentifier(subStr) == false

&& isDelimiter(str[right - 1]) == false) printf("'%s' IS NOT A VALID IDENTIFIER\n", subStr);

left = right;

// DRIVER FUNCTION

int main()

// maximum legth of string is 100 here char str[100] = "(4 + y *3 ) # comment";

parse(str); // calling the parse function

return (0);

}
OUTPUT:

Sample I/P in C Sample Lexical output


print (4 + y *3 ) # comment (keyword , "print") (delim,
"(")
(int, 4) (punct,"+")
(id , "y")
(punct,"*") (int, 3)
(delim, ")")
2. Write a program to test whether a given identifier is valid or not.
CODE:
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package cc_lab4;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class CC_Lab4 {


public static void main(String[] args) {
// TODO code application logic here

// TODO code application logic here


String[] input = {"123var","abc","var-1","_val","value_first","*nonvar","value2021"};
//single line comment RE
Pattern re1 = Pattern.compile("^[A-Za-z$_][\\w]*$");
Matcher m;
for (int i = 0; i < input.length; i++) {
m = re1.matcher(input[i]);
if(m.find()){
System.out.println("Input: "+input[i]+" - Valid variable");
}
else{
System.out.println("Input: "+input[i]+" - Invalid variable");
}
}
}
}
OUTPUT
3. Write a program to eliminate the Left Recursion using the given in Algorithm 4.19 of
Compilers Principles, Techniques and Tools book.
E→E+T|T
T → T * F |F
F → (E) | id
CODE:
#include<iostre>
#include<string>
using namespace
std; int main()
{ string
ip,op1,op2,temp; int
sizes[10] = {};
char
c; int
n,j,l;
cout<<"Enter the Parent Non-Terminal
: "; cin>>c;
ip.push_back(
c); op1 += ip +
"\'->";
ip += "->";
op2+=ip;
cout<<"Enter the number of productions
: "; cin>>n;
for(int i=0;i<n;i++)
{ cout<<"Enter Production "<<i+1<<" : ";
cin>>temp;
sizes[i] =
temp.size();
ip+=temp;
if(i!=n-1)
ip += "|";
}
cout<<"Production Rule :
"<<ip<<endl; for(int i=0,k=3;i<n;i+
+)
{
if(ip[0] == ip[k])
{
cout<<"Production "<<i+1<<" has left recursion."<<endl; if(ip[k] != '#')
{
for(l=k+1;l<k+sizes[i];l++)
op1.push_back(ip[l]);
k=l+1;
op1.push_back(ip[
0]); op1 += "\'|";
}
}
else
{
cout<<"Production "<<i+1<<" does not have left
recursion."<<endl; if(ip[k] != '#')
{
for(j=k;j<k+sizes[i];j
++)
op2.push_back(ip[
j]);
k=j+1;
op2.push_back(ip[
0]); op2 += "\'|";
}
else
{
op2.push_back(ip[
0]); op2 += "\'";
}}}
op1 += "#";
cout<<op2<<e
ndl;
cout<<op1<<e
ndl; return 0;}

OUTPUT:

Grammar Output
E -> E + T | T E -> TE’
T -> T * F |F E’ -> +TE’ | Є
F -> (E) | id T -> FT’
T’ -> *FT’ | Є
F -> (E) | id
4a. Write a program to simulate lexical analyzer for validating operators.
CODE:
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package cc_lab5;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class CC_Lab5 {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
String[] input = {"+", "2021", "xyz", "i++", "j++", "/", "34", "2abc2", "<", ">", "=", "<=", ">=="};
//RE for arithmetic operators
Pattern re1 = Pattern.compile("^[+-/*%]|[$_A-Za-z]*[A-Za-z0-9_]+[++]|[$_A-Za-z]*[A-Za-z0-9_]*[--]$");
//RE for relational operators
Pattern re2 = Pattern.compile("^[<>]?[=]?$");
//RE for logical and ternary operators
Pattern re3 = Pattern.compile("^[|&!?:]$");
Matcher m1, m2, m3;
for (int i = 0; i < input.length; i++) {
m1 = re1.matcher(input[i]);
m2 = re2.matcher(input[i]);
m3 = re3.matcher(input[i]);
if ( m1.find() | m2.find() | m3.find() ) {
System.out.println("Input: " + input[i] + " - Valid operator");
} else {
System.out.println("Input: " + input[i] + " - Invalid operator");
}
}
}
}
OUTPUT
4b. Design a lexical analyzer for given language and the lexical analyzer should ignore redundant
spaces, tabs and new lines. It should also ignore comments. Although the syntax specification
states that identifiers can be arbitrarily long, you may restrict the length to some reasonable
value. Simulate the same in C language.
CODE:
#include<string.h>
#include<conio.h>
#include<ctype.h>
#include<stdio.h>
void main()
{
FILE *f1;
char c,str[10];
int lineno=1,num=0,i=0;
printf("\nEnter the c program\n");
f1=fopen("input.txt","w");
while((c=getchar())!=EOF)
putc(c,f1);
fclose(f1);
f1=fopen("input.txt","r");
while((c=getc(f1))!=EOF) // TO READ THE GIVEN FILE
{
if(isdigit(c)) // TO RECOGNIZE NUMBERS
{
num=c-48;
c=getc(f1);
while(isdigit(c))
{
num=num*10+(c-48);
c=getc(f1);
}
printf("%d is a number \n",num);
ungetc(c,f1);
}
else if(isalpha(c)) // TO RECOGNIZE KEYWORDS AND IDENTIFIERS
{
str[i++]=c;
c=getc(f1);
while(isdigit(c)||isalpha(c)||c=='_'||c=='$')
{
str[i++]=c;
c=getc(f1);
}
str[i++]='\0';
if(strcmp("for",str)==0||strcmp("while",str)==0||strcmp("do",str)==0||
strcmp("int",str)==0||strcmp("float",str)==0||strcmp("char",str)==0||
strcmp("double",str)==0||strcmp("static",str)==0||
strcmp("switch",str)==0||strcmp("case",str)==0) // TYPE 32 KEYWORDS
printf("%s is a keyword\n",str);
else
printf("%s is a identifier\n",str);
ungetc(c,f1);
i=0;
}
else if(c==' '||c=='\t') // TO IGNORE THE SPACE
printf("\n");
else if(c=='\n') // TO COUNT LINE NUMBER
lineno++;
else // TO FIND SPECIAL SYMBOL
printf("%c is a special symbol\n",c);
}
printf("Total no. of lines are: %d\n",lineno);
fclose(f1);
getch();
}
OUTPUT:

5. Implement the stack program for the following grammar which take the input string
“)id *+id$”
E→TE'
E'→+TE/ ε
T→FT'
T`→*FT'/ ε
F→ (E)/id
CODE:
#include <cstdlib>
#include <iostream>
class arrayStack
{
protected char arr[];
protected int top,size;
public arrayStack()
{
size=20;
arr=new char[size];
top=-1;
}
public void push(char i)
{
if (top + 1>= size)
{
print("error, skip");}
if (top+1< size){
arr[++top] = i;}}
public char pop()
{
return arr[top--];}
public void display()
{
for (int i= top; i >=0; i--)
print(arr[i]);}
}

public static void main(String[ ] args)throws Exception{


String [ ][ ] Transition=new String[20][20];
int alphaset,stateset;
ArrayList<String> alphabet;
ArrayList<String> alpha;
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
print ("please enter the no.of terminals: ");
alphaset=Integer.parseInt(br.readLine( ));
print("please enter the no of Non Terminals: ");
stateset=Integer.parseInt(br.readLine());
print("please enter starting non terminal in th grammar: ");
char state[ ]=br.readLine( ).toCharArray();
print("please enter all the terminal simultaneously");
String alphabets[ ]=new String[alphaset];
for (int i=0;i<alphaset;i++)
{
alphabets[i]=br.readLine();
}
alphabet=new ArrayList<>();
for (int i=0;i<alphaset;i++)
{
alphabet.add(alphabets[i]);
}
print("please enter all the non terminals simultaneously");
String alphas[]=new String[stateset];
for(int i=0;i<stateset;i++)
{
alphas[i]=br.readLine();
}
alpha= new ArrayList<>();
for (int i=0;i<stateset;i++)
{
alpha.add(alphas[i]);
}
print("For epselon use @");
for (int s=0;s<stateset;s++)
{
print("enter the row enteries of transition table");
for (int r=0;r<alphaset;r++)
{
String int1=br.readLine();
Transition[s][r]=int1;
}
}
for (int s=0;s<stateset;s++)
{
for (int r=0;r<alphaset;r++)
{
print(Transition[s][r]+"\t\t"); }
print();
}
int y;
do{
print("give input to the parser \n");
print("end your input with $# character \n");
String input=br.readLine();
arrayStack stk=new arrayStack();
stk.push('$');
stk.push(state[0]);
int index=0;
print("Stack\t\t"+"Input\t\t"+"Output");
while(input.charAt(index)!='#')
{
stk.display();
char char3=input.charAt(index);
String char1=""+input.charAt(index);
int index1=alphabet.indexOf(char1);
String char2=""+stk.pop();
int index2=alpha.indexOf(char2);
if(Transition[index2][index1].equals("NULL")){
System.out.println("Given String is not Accepted\n");
break;
}
print("\t\t"+input.charAt(index)+"\t\t"+Transition[index2][index1]);
String c[]=Transition[index2][index1].split("->");
char d[]=c[1].toCharArray();
for (int i=d.length-1;i>=0;i--){
if (d[i]!='@'){
stk.push(d[i]);
}}
char ch=stk.pop();
if (ch==char3){
index++;}
else if(ch=='$'){
stk.push(ch);}
else{
stk.push(ch);}}
if ((input.charAt(index-1)=='$')){
print("Parsing Completed Successfully\n");
}
print("So you want to continue(1/0)?\n");
Scanner scan=new Scanner(System.in);
y=scan.nextInt();
}while(y==1);
}}

OUTPUT
For the string “)id*+id$” given grammar will generate an error but for any other string like “a+a*a$” given
grammar will be parsed completely.
• Here A=E`, B=T` and a=id

6. Construct a recursive descent parsing for the above grammar.


CODE:
#include<stdio.h>
#include<conio.h>
#include<string.h>
char input[100];
int i,l;
void main()
{
clrscr();
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:"); gets(input);
if(E())
{
if(input[i+1]=='\0') printf("\nString is accepted"); else
printf("\nString is not accepted");

}
else
printf("\nString not accepted"); getch();
} E()
{ if(T())
{ if(EP())
return(1); else return(0);
}
Else
return(0);

} EP()
{

if(input[i]=='+')

{ i++;
if(T())
{ if(EP())
return(1); else return(0);
}

else return(0);
}

else return(1);
} T()
{

if(F())

{ if(TP())
return(1); else return(0);
}

else return(0);
} TP()
{

if(input[i]=='*')

{ i++;
if(F())

{ if(TP())
return(1); else return(0);
}

else return(0);
}

else return(1);
} F()
{

if(input[i]=='(')

{ i++;
if(E())

if(input[i]==')')

{ i++;
return(1);

}
else return(0);
}
else return(0);
}

else if(input[i]>='a'&&input[i]<='z'||input[i]>='A'&&input[i]<='Z')

{ i++;
return(1);

else return(0);
}
OUTPUT:
7. Write a program to implement operator precedence parsing.
#include<iostream>
#include<string>
#include<deque>
using namespace std;
int n,n1,n2;
int getPosition(string arr[], string q, int size)
{
for(int i=0;i<size;i++)
{
if(q == arr[i])
return i;
}
return -1;
}
int main()
{
string prods[10],leads[10],trails[10],nonterms[10],terms[10];
char op_table[20][20] = {};
cout<<"Enter the number of productions : ";
cin>>n;
cin.ignore();
cout<<"Enter the productions"<<endl;
for(int i=0;i<n;i++)
{
getline(cin,prods[i]);
}
cout<<"Enter the number of Terminals : ";
cin>>n2;
cin.ignore();
cout<<"Enter the Terminals"<<endl;
for(int i=0;i<n2;i++)
{
cin>>terms[i];
}
terms[n2] = "$";
n2++;
cout<<"Enter the number of Non-Terminals : ";
P a g e 18 | 41
cin>>n1;
cin.ignore();
for(int i=0;i<n1;i++)
{
cout<<"Enter Non-Terminal : ";
getline(cin,nonterms[i]);
cout<<"Enter Leads of "<<nonterms[i]<<" : ";
getline(cin,leads[i]);
cout<<"Enter Trails of "<<nonterms[i]<<" : ";
getline(cin,trails[i]);
}
cout<<"Enter the Rules (exit to stop)"<<endl;
string rule = "";
while(rule != "exit")
{
getline(cin,rule);
if(rule[0] == '1')
{
int row = getPosition(terms,rule.substr(2,1),n2);
int column = getPosition(terms,rule.substr(4,1),n2);
op_table[row][column] = '=';
}
if(rule[0] == '2')
{
int ntp = getPosition(nonterms,rule.substr(4,1),n1);
int row = getPosition(terms,rule.substr(2,1),n2);
for(int j=0;j<leads[ntp].size();j++)
{
int col = getPosition(terms,leads[ntp].substr(j,1),n2);
op_table[row][col] = '<';
}
}
if(rule[0] == '3')
{
int col = getPosition(terms,rule.substr(4,1),n2);
int ntp = getPosition(nonterms,rule.substr(2,1),n1);
for(int j=0;j<trails[ntp].size();j++)
{
int row = getPosition(terms,trails[ntp].substr(j,1),n2);
op_table[row][col] = '>';
}
}
}
for(int j=0;j<leads[0].size();j++)
{
int col = getPosition(terms,leads[0].substr(j,1),n2);
op_table[n2-1][col] = '<';
}
for(int j=0;j<trails[0].size();j++)
{
int row = getPosition(terms,trails[0].substr(j,1),n2);
op_table[row][n2-1] = '>';
}
P a g e 19 | 41
cout<<endl;
cout<<"Grammar"<<endl;
for(int i=0;i<n;i++)
{
cout<<prods[i]<<endl;
}
//Display Table
for(int j=0;j<n2;j++)
cout<<"\t"<<terms[j];
cout<<endl;
for(int i=0;i<n2;i++)
{
cout<<terms[i]<<"\t";
for(int j=0;j<n2;j++)
{
cout<<op_table[i][j]<<"\t";
}
cout<<endl;
}
//Parsing String
char c;
do{
string ip;
deque<string> op_stack;
op_stack.push_back("$");
cout<<"Enter the string to be parsed : ";
getline(cin,ip);
ip.push_back('$');
cout<<"Stack\ti/p Buffer\tRelation\tAction"<<endl;
while(true)
{
for(int i=0;i<op_stack.size();i++)
cout<<op_stack[i];
cout<<"\t";
cout<<ip<<"\t";
int row = getPosition(terms,op_stack.back(),n2);
int column = getPosition(terms,ip.substr(0,1),n2);
if(op_table[row][column] == '<')
{
op_stack.push_back("<");
op_stack.push_back(ip.substr(0,1));
ip = ip.substr(1);
cout<<"\t"<<"<\t\tPush";
}
else if(op_table[row][column] == '=')
{
op_stack.push_back("=");
op_stack.push_back(ip.substr(0,1));
ip = ip.substr(1);
cout<<"\t"<<"=\t\tPush";
}
else if(op_table[row][column] == '>')
{
P a g e 20 | 41
string last;
do
{
op_stack.pop_back();
last = op_stack.back();
op_stack.pop_back();
}while(last != "<");
cout<<"\t"<<">\t\tPop";
}
else
{
if(ip[0] == '$' && op_stack.back() == "$")
{
cout<<"\t\t\tAccept\nString Parsed."<<endl;
break;
}
else
{
cout<<endl<<"String cannot be Parsed."<<endl;
break;
}
}
cout<<endl;
}
cout<<"Continue?(Y/N) ";
cin>>c;
cin.ignore();
}while(c=='y' || c=='Y');
return 0;
}

P a g e 21 | 41
8. Consider following grammar
S → DF | AF | DB | AB
X→ AY | BY | a | b

P a g e 22 | 41
Y→ AY | BY | a | b,
D→ AX
F→ BX
A→ a
B→ b
Write the C/C++/Java/Python program using the CYK algorithm to recognize the
strings produced by the above grammar.

Sample String Sample Output


aaa No
ab Yes
ababb Yes

CODE:
#include<stdio.h>
#include<conio.h>
#include<string.h>
char input[100];
int i,l;
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:");
gets(input);
if(E())
{
if(input[i+1]=='\0')
printf("\nString is accepted");
else
printf("\nString is not accepted");
}
else
printf("\nString not accepted");
getch();
}
E()
{if(T()){
if(EP())
return(1);
else
return(0);}
else
return(0);}
P a g e 23 | 41
EP()
{if(input[i]=='+')
{i++;
if(T()){
if(EP())
return(1);
else
return(0);}
else
return(0);}
else
return(1);}
T()
{if(F())
{if(TP())
return(1);
else
return(0);}
else
return(0);}
TP()
{if(input[i]=='*')
{i++;
if(F())
{if(TP())
return(1);
else
return(0);}
else
return(0);}
else
return(1);}
F()
{if(input[i]=='(')
{i++;
if(E())
{if(input[i]==')')
{i++;
return(1);}
else
return(0);}
else
return(0);}
else if(input[i]>='a'&&input[i]<='z'||input[i]>='A'&&input[i]<='Z')
{i++;

P a g e 24 | 41
return(1);}
else
return(0);}
OUTPUT:

9. Write a C/C++/ Java/Python program to implement the LR(0) and SLR(1) parser.
a. Create the LR(0) item sets .
b. Make LR(0) and SLR(1) table.

P a g e 25 | 41
c. Create the parser and call the table according to parser required.
d. Print the error also.
CODE:

P a g e 26 | 41
10. Write a program for implementing the functionalities of predictive parser for the
mini language as follows:
{int a[3],t1,t2;
T1=2;
A[0]=1;a[1]=2;a[t]=3;
T2=-( a[2]+t1*6)/(a[2]-t1);
If t2>5then
Print(t2)
Else{
Int t3;
T3=99;
T2=25;
Print(-t1+t2*t3);/*this is a comment on 2 lines*/
}endif
}
CODE:
#include<stdio.h>
#include<conio.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];
numr(char c)
{
switch(c)
{
case 'S': return 0; case 'A': return 1; case 'B': return 2; case 'C': return 3; case 'a': return 0; case
'b': return 1; case 'c': return 2; case 'd': return 3; case '$': return 4;
}
return(2);
}
void main()
{
int i,j,k;
clrscr(); for(i=0;i<5;i++) for(j=0;j<6;j++) strcpy(table[i][j]," ");
printf("\nThe following is the predictive parsing table for the following grammar:\n");
for(i=0;i<7;i++)
printf("%s\n",prod[i]); printf("\nPredictive parsing table is\n"); fflush(stdin);
for(i=0;i<7;i++)
{
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++)

P a g e 27 | 41
{
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");
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");
}
getch();
}
INPUT & OUTPUT:
The following is the predictive parsing table for the following grammar: S->A
A->Bb
A->Cd
B->aB
B->@
C->Cc
C->@
Predictive parsing table is

abcd$

S S->A S->A S->A S->A

A A->Bb A->Bb A->Cd A->Cd

B B->aB B->@ B->@ B->@

C C->@ C->@ C->@


P a g e 28 | 41
11. Write a program to find the FIRST for all grammar symbols and FOLLOW for all
Non-Terminals in a given grammar.

S → T S’
S’ → +S | ε
T → F T’
T’ → T | ε
F → P F’
F’ → *F | ε
P → (S) | x | y | ep
CODE:
#include<stdio.h>
#include<ctype.h>
#include<string.h>

// Functions to calculate Follow


void followfirst(char, int, int);
void follow(char c);

// Function to calculate First


void findfirst(char, int, int);

int count, n = 0;

// Stores the final result


// of the First Sets
char calc_first[20][100];

// Stores the final result


// of the Follow Sets
char calc_follow[20][100];
int m = 0;

// Stores the production rules


char production[20][20];
char f[20], first[20];
int k;
char ck;
int e;

P a g e 29 | 41
int main(int argc, char **argv)
{
int jm = 0;
int km = 0;
int i, choice;
char c, ch;
count = 13;

// The Input grammar


strcpy(production[0], "S=TA");
strcpy(production[1], "A=+S");
strcpy(production[2], "A=#");
strcpy(production[3], "T=FB");
strcpy(production[4], "B=T");
strcpy(production[5], "B=#");
strcpy(production[6], "F=PC");
strcpy(production[7], "C=*F");
strcpy(production[8], "C=#");
strcpy(production[9], "P=(S)");
strcpy(production[10], "P=x");
strcpy(production[11], "P=y");
strcpy(production[12], "P=ep");

int kay;
char done[count];
int ptr = -1;

// Initializing the calc_first array


for(k = 0; k < count; k++) {
for(kay = 0; kay < 100; kay++) {
calc_first[k][kay] = '!';
}
}
int point1 = 0, point2, xxx;

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


{
c = production[k][0];
point2 = 0;
xxx = 0;

P a g e 30 | 41
// Checking if First of c has
// already been calculated
for(kay = 0; kay <= ptr; kay++)
if(c == done[kay])
xxx = 1;

if (xxx == 1)
continue;

// Function call
findfirst(c, 0, 0);
ptr += 1;

// Adding c to the calculated list


done[ptr] = c;
printf("\n First(%c) = { ", c);
calc_first[point1][point2++] = c;

// Printing the First Sets of the grammar


for(i = 0 + jm; i < n; i++) {
int lark = 0, chk = 0;

for(lark = 0; lark < point2; lark++) {

if (first[i] == calc_first[point1][lark])
{
chk = 1;
break;
}
}
if(chk == 0)
{
printf("%c, ", first[i]);
calc_first[point1][point2++] = first[i];
}
}
printf("}\n");
jm = n;
point1++;
}
P a g e 31 | 41
printf("\n");
printf("-----------------------------------------------\n\n");
char donee[count];
ptr = -1;

// Initializing the calc_follow array


for(k = 0; k < count; k++) {
for(kay = 0; kay < 100; kay++) {
calc_follow[k][kay] = '!';
}
}
point1 = 0;
int land = 0;
for(e = 0; e < count; e++)
{
ck = production[e][0];
point2 = 0;
xxx = 0;

// Checking if Follow of ck
// has alredy been calculated
for(kay = 0; kay <= ptr; kay++)
if(ck == donee[kay])
xxx = 1;

if (xxx == 1)
continue;
land += 1;

// Function call
follow(ck);
ptr += 1;

// Adding ck to the calculated list


donee[ptr] = ck;
printf(" Follow(%c) = { ", ck);
calc_follow[point1][point2++] = ck;

// Printing the Follow Sets of the grammar


for(i = 0 + km; i < m; i++) {
int lark = 0, chk = 0;

P a g e 32 | 41
for(lark = 0; lark < point2; lark++)
{
if (f[i] == calc_follow[point1][lark])
{
chk = 1;
break;
}
}
if(chk == 0)
{
printf("%c, ", f[i]);
calc_follow[point1][point2++] = f[i];
}
}
printf(" }\n\n");
km = m;
point1++;
}
}

void follow(char c)
{
int i, j;

// Adding "$" to the follow


// set of the start symbol
if(production[0][0] == c) {
f[m++] = '$';
}
for(i = 0; i < 20; i++)
{
for(j = 1;j < 20; j++)
{
if(production[i][j] == c)
{
if(production[i][j+1] != '\0')
{
// Calculate the first of the next
// Non-Terminal in the production
followfirst(production[i][j+1], i, (j+2));
}

if(production[i][j+1]=='\0' && c!=production[i][0])

P a g e 33 | 41
{
// Calculate the follow of the Non-Terminal
// in the L.H.S. of the production
follow(production[i][1]);
}
}
}
}
}

void findfirst(char c, int q1, int q2)


{
int j;

// The case where we


// encounter a Terminal
if(!(isupper(c))) {
first[n++] = c;
}
for(j = 0; j < count; j++)
{
if(production[j][0] == c)
{
if(production[j][2] == '#')
{
if(production[q1][q2] == '\0')
first[n++] = '#';
else if(production[q1][q2] != '\0'
&& (q1 != 0 || q2 != 0))
{
// Recursion to calculate First of New
// Non-Terminal we encounter after epsilon
findfirst(production[q1][q2], q1, (q2+1));
}
else
first[n++] = '#';
}
else if(!isupper(production[j][2]))
{
first[n++] = production[j][2];
}
else
{
// Recursion to calculate First of
P a g e 34 | 41
// New Non-Terminal we encounter
// at the beginning
findfirst(production[j][2], j, 3);
}
}
}
}

void followfirst(char c, int c1, int c2)


{
int k;

// The case where we encounter


// a Terminal
if(!(isupper(c)))
f[m++] = c;
else
{
int i = 0, j = 1;
for(i = 0; i < count; i++)
{
if(calc_first[i][0] == c)
break;
}

//Including the First set of the


// Non-Terminal in the Follow of
// the original query
while(calc_first[i][j] != '!')
{
if(calc_first[i][j] != '#')
{
f[m++] = calc_first[i][j];
}
else
{
if(production[c1][c2] == '\0')
{
// Case where we reach the
// end of a production
follow(production[c1][0]);
}
else

P a g e 35 | 41
{
// Recursion to the next symbol
// in case we encounter a "#"
followfirst(production[c1][c2], c1, c2+1);
}
}
j++;
}
}
}
OUTPUT:

12. Convert The BNF (Backus-Naur Form) rules into YACC (Yet Another
Compiler Compiler) form and write code to generate abstract syntax tree.

CODE:
Lex<Bnf.L>
%{
#include"y.tab.h"
#include<stdio.h>
#include<string.h>

P a g e 36 | 41
int LineNo=1;
%}
identifier [a-zA-Z][_a-zA-Z0-9]* number [0-9]+|([0-9]*\.[0-9]+)
%%
main\(\) return MAIN; if return IF;
else return ELSE; while return WHILE; int |
char |
float return TYPE;
{identifier} {strcpy(yylval.var,yytext); return VAR;}
{number} {strcpy(yylval.var,yytext); return NUM;}
\< |
\> |
\>= |
\<= |
== {strcpy(yylval.var,yytext); return RELOP;}
[ \t] ;
\n LineNo++;
. return yytext[0];

%%
Yacc <Bnf.Y>
%{
#include<string.h> #include<stdio.h> struct quad
{
char op[5]; char arg1[10]; char arg2[10]; char result[10];
}QUAD[30];
struct stack
{
int items[100]; int top;
}stk;
int Index=0,tIndex=0,StNo,Ind,tInd; extern int LineNo;
%}
%union
{
char var[10];
}
%token <var> NUM VAR RELOP
%token MAIN IF ELSE WHILE TYPE
%type <var> EXPR ASSIGNMENT CONDITION IFST ELSEST WHILELOOP
%left '-' '+'
%left '*' '/'
%%
PROGRAM : MAIN BLOCK
;
BLOCK: '{' CODE '}'
;
CODE: BLOCK
| STATEMENT CODE
P a g e 37 | 41
| STATEMENT
;
STATEMENT: DESCT ';'
| ASSIGNMENT ';'
| CONDST
| WHILEST

;
DESCT: TYPE VARLIST
;
VARLIST: VAR ',' VARLIST
| VAR
;
ASSIGNMENT: VAR '=' EXPR{
strcpy(QUAD[Index].op,"="); strcpy(QUAD[Index].arg1,$3); strcpy(QUAD[Index].arg2,"");
strcpy(QUAD[Index].result,$1); strcpy($$,QUAD[Index++].result);
};
EXPR: EXPR '+' EXPR {AddQuadruple("+",$1,$3,$$);}
| EXPR '-' EXPR {AddQuadruple("-",$1,$3,$$);}
| EXPR '*' EXPR {AddQuadruple("*",$1,$3,$$);}
| EXPR '/' EXPR {AddQuadruple("/",$1,$3,$$);}
| '-' EXPR {AddQuadruple("UMIN",$2,"",$$);}
| '(' EXPR ')' {strcpy($$,$2);}
| VAR
| NUM
;
CONDST: IFST{
Ind=pop(); sprintf(QUAD[Ind].result,"%d",Index); Ind=pop();
sprintf(QUAD[Ind].result,"%d",Index);
}
| IFST ELSEST
;
IFST: IF '(' CONDITION ')' {
strcpy(QUAD[Index].op,"=="); strcpy(QUAD[Index].arg1,$3);
strcpy(QUAD[Index].arg2,"FALSE"); strcpy(QUAD[Index].result,"-1"); push(Index);
Index++;
}
BLOCK {
strcpy(QUAD[Index].op,"GOTO"); strcpy(QUAD[Index].arg1,"");
strcpy(QUAD[Index].arg2,"");
strcpy(QUAD[Index].result,"-1");

push(Index); Index++;
};
ELSEST: ELSE{
tInd=pop(); Ind=pop(); push(tInd);
sprintf(QUAD[Ind].result,"%d",Index);
} BLOCK{
P a g e 38 | 41
Ind=pop(); sprintf(QUAD[Ind].result,"%d",Index);
};
CONDITION: VAR RELOP VAR {AddQuadruple($2,$1,$3,$$); StNo=Index-1;
}
| VAR
| NUM
;
WHILEST: WHILELOOP{
Ind=pop(); sprintf(QUAD[Ind].result,"%d",StNo); Ind=pop();
sprintf(QUAD[Ind].result,"%d",Index);
};
WHILELOOP: WHILE '(' CONDITION ')' {
strcpy(QUAD[Index].op,"=="); strcpy(QUAD[Index].arg1,$3);
strcpy(QUAD[Index].arg2,"FALSE"); strcpy(QUAD[Index].result,"-1"); push(Index);
Index++;
}
BLOCK {
strcpy(QUAD[Index].op,"GOTO"); strcpy(QUAD[Index].arg1,"");
strcpy(QUAD[Index].arg2,"");
strcpy(QUAD[Index].result,"-1"); push(Index);
Index++;
};
%%
extern FILE *yyin;

int main(int argc,char *argv[])


{
FILE *fp; int i; if(argc>1)
{
fp=fopen(argv[1],"r"); if(!fp)
{
printf("\n File not found"); exit(0);
}
yyin=fp;

}
yyparse();
printf("\n\n\t\t ----------------------------\n\t\t Pos Operator Arg1 Arg2
Result\n\t\t--------------------
");
for(i=0;i<Index;i++)
{
printf("\n\t\t %d\t %s\t %s\t %s\t
%s",i,QUAD[i].op,QUAD[i].arg1,QUAD[i].arg2,QUAD[i].result);
}
printf("\n\t\t "); printf("\n\n");
return 0;
}
P a g e 39 | 41
void push(int data)
{s tk.top++;
if(stk.top==100)
{
printf("\n Stack overflow\n"); exit(0);
}s tk.items[stk.top]=data;
} int pop()
{ int data; if(stk.top==-1)
{
printf("\n Stack underflow\n"); exit(0);
}

data=stk.items[stk.top--]; return data;


}
void AddQuadruple(char op[5],char arg1[10],char arg2[10],char result[10])
{s trcpy(QUAD[Index].op,op);
strcpy(QUAD[Index].arg1,arg1); strcpy(QUAD[Index].arg2,arg2);
sprintf(QUAD[Index].result,"t%d",tIndex++); strcpy(result,QUAD[Index++].result);
}
yyerror()
{
printf("\n Error on line no:%d",LineNo);
}

Input<Vi Test .C> main()


{ int a,b,c; if(a<b)
{a=a+b;}

while(a<b)
{a=a+b;} if(a<=b)
{c=a-b;} else
{c=a+b;}
}

OUTPUT:

P a g e 40 | 41
<<< GOOD LUCK>>>

P a g e 41 | 41

You might also like