Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

CD Lab 3

Download as pdf or txt
Download as pdf or txt
You are on page 1of 18

NAME :Cheenepalli sai pavan

SCHOLAR NUMBER : 2211201144

SUBJECT :CD LAB - 3

SECTION : 01

1)Write a program to implement Recursive Descent Parsing with backtracking


(Brute Force Method). S →cAd A→ ab/a

Code:

#include<iostream>

#include<string>

using namespace std;

string input;

int pos = 0;

// Function declarations

bool S();

bool A();

bool match(char terminal) {

if (pos < input.length() && input[pos] == terminal) {

pos++;

return true;
}

return false;

bool A() {

// Try matching "ab"

int backtrack = pos;

if (match('a') && match('b')) {

return true;

// Backtrack and try matching "a"

pos = backtrack;

if (match('a')) {

return true;

return false;

bool S() {

// Match "cAd"

if (match('c') && A() && match('d')) {

return true;

return false;
}

int main() {

cout << "Enter the input string: ";

cin >> input;

if (S() && pos == input.length()) {

cout << "String accepted by the grammar." << endl;

} else {

cout << "String rejected by the grammar." << endl;

return 0;

Output :

Input: cad

Output: String accepted by the grammar.

Input: cabd

Output: String accepted by the grammar.

Input: cbad

Output: String rejected by the grammar.


2)Write a Program to implement Predictive Parser for the given grammar. Give
input string as “ba”. S ->AaAb | BbBa, A -> Є B->Є

Code:

#include<iostream>

#include<stack>

#include<string>

using namespace std;

string input;

int pos = 0;

stack<char> parseStack;

void predictiveParser(string input) {

parseStack.push('$'); // End of input

parseStack.push('S'); // Start symbol

while (!parseStack.empty()) {

char top = parseStack.top();

char currentInput = input[pos];

if (top == '$' && currentInput == '$') {

cout << "String accepted!" << endl;

return;
}

if (top == currentInput) {

parseStack.pop();

pos++;

} else if (top == 'S') {

parseStack.pop();

parseStack.push('b'); parseStack.push('A'); parseStack.push('B');

} else if (top == 'A' || top == 'B') {

parseStack.pop(); // A -> ε or B -> ε

} else {

cout << "Error in parsing. String rejected." << endl;

return;

int main() {

cout << "Enter input string ending with $: ";

cin >> input;

predictiveParser(input);

return 0;
}

Output :

Input: ba$

Output: String accepted!

Input: bb$

Output: String rejected.

3)Design and implement an LL(1) parser for a simple expression grammar. The
language supports basic arithmetic expressions with the following features:
Operators: +, -, *, / Operands: Integer values Parentheses: ( and ) for grouping
Unary operators (e.g., -3), floating-point numbers, or exponentiation (e.g., ^
operator). Solution :

1. You can consider the following example grammar: E → TE' E' → +TE' |
-TE' | ε T → FT' T' → *FT' | /FT' | ε F → (E) | id

2. Compute FIRST and FOLLOW Sets

3. Construct the LL(1) Parsing Table

4. Implement the LL(1) Parser

5. Test the Parser on some input string.

Code:

#include <iostream>

#include <stack>
#include <map>

#include <string>

using namespace std;

// Parsing Table

map<pair<char, char>, string> parsingTable;

// Function to initialize the parsing table

void initializeParsingTable() {

parsingTable[{'E', 'id'}] = "TE'";

parsingTable[{'E', '('}] = "TE'";

parsingTable[{'E\'', '+'}] = "+TE'";

parsingTable[{'E\'', '-'}] = "-TE'";

parsingTable[{'E\'', ')'}] = "ε";

parsingTable[{'E\'', '$'}] = "ε";

parsingTable[{'T', 'id'}] = "FT'";

parsingTable[{'T', '('}] = "FT'";

parsingTable[{'T\'', '+'}] = "ε";

parsingTable[{'T\'', '-'}] = "ε";

parsingTable[{'T\'', '*'}] = "*FT'";

parsingTable[{'T\'', '/'}] = "/FT'";

parsingTable[{'T\'', ')'}] = "ε";

parsingTable[{'T\'', '$'}] = "ε";


parsingTable[{'F', 'id'}] = "id";

parsingTable[{'F', '('}] = "(E)";

// LL(1) Parser

void parseLL1(string input) {

stack<char> parseStack;

parseStack.push('$');

parseStack.push('E'); // Start symbol

input.push_back('$'); // End of input symbol

int pos = 0;

while (!parseStack.empty()) {

char top = parseStack.top();

char currentInput = input[pos];

if (top == currentInput) {

parseStack.pop();

pos++;

} else if (parsingTable.find({top, currentInput}) != parsingTable.end()) {

parseStack.pop();

string production = parsingTable[{top, currentInput}];

if (production != "ε") {
for (int i = production.length() - 1; i >= 0; i--) {

parseStack.push(production[i]);

} else {

cout << "Parsing error!" << endl;

return;

cout << "String accepted by the grammar." << endl;

int main() {

initializeParsingTable();

string input;

cout << "Enter the input expression: ";

cin >> input;

parseLL1(input);

return 0;

}
Output :

Input: id+id$

Output: String accepted by the grammar.

Input: id*id$

Output: String accepted by the grammar.

Input: id+$

Output: Parsing error!

4)Design and implement a parser for a simple arithmetic expression language


using Yacc. The language supports the following: Operators: +, -, *, / Operands:
Integer values Parentheses: (and) for grouping handle floating-point numbers and
additional operators (like ^ for exponentiation). Solution : Steps to be followed
while solving the assignment Step 1: Define the Grammar: Write the context-free
grammar (CFG) for the above language. Step 2: Write Lex Specifications: Create a
Lex specification file to identify tokens in the input string. Step 3: Write Yacc
Specifications: Use Yacc to generate the parser code from the Yacc specification
file. Also, use Lex to generate the lexical analyzer. Link these together to form the
complete parser program. Step 4: Generate the Parser Step 5: Test the Parser

Code:
Lex code :

%{

#include "y.tab.h"
%}

%%

[0-9]+(\.[0-9]+)? { yylval.fval = atof(yytext); return NUMBER; }

"+" { return '+'; }

"-" { return '-'; }

"*" { return '*'; }

"/" { return '/'; }

"^" { return '^'; }

"(" { return '('; }

")" { return ')'; }

[ \t\n]+ ; // Ignore whitespace

. { printf("Unknown character: %s\n", yytext); }

%%

int yywrap() {

return 1;

YACC Code :
%{

#include <stdio.h>

#include <math.h>

void yyerror(const char *s);

int yylex();

%}

%union {

double fval; // For floating-point values

%token <fval> NUMBER

%left '+' '-'

%left '*' '/'

%right '^'

%nonassoc UMINUS // Unary minus

%%

expr:

expr '+' term { $$ = $1 + $3; }

| expr '-' term { $$ = $1 - $3; }

| term { $$ = $1; }
;

term:

term '*' factor { $$ = $1 * $3; }

| term '/' factor { $$ = $1 / $3; }

| factor { $$ = $1; }

factor:

'(' expr ')' { $$ = $2; }

| NUMBER { $$ = $1; }

| factor '^' factor { $$ = pow($1, $3); }

| '-' factor %prec UMINUS { $$ = -$2; }

%%

int main() {

printf("Enter an expression: ");

yyparse();

return 0;

void yyerror(const char *s) {


fprintf(stderr, "Error: %s\n", s);

Compile Code :

yacc -d yacc.y

lex lex.l

gcc lex.yy.c y.tab.c -lm -o parser

Test parser :

./parser

Enter an expression: (3 + 5) * 2 ^ 3

Result: 64

Output :

Enter an expression: (3 + 2) ^ 2

Result: 25

5)Use YACC to Convert Binary to Decimal (including fractional numbers).

Code:

Lex:

%{

#include "y.tab.h"

%}
%%

[01]+ { yylval.str = strdup(yytext); return BINARY; }

"\." { return '.'; }

[ \t\n]+ ; // Ignore whitespace

. { printf("Unknown character: %s\n", yytext); }

%%

int yywrap() {

return 1;

Yacc:

%{

#include <stdio.h>

#include <math.h>

#include <string.h>

void yyerror(const char *s);

int yylex();
double binaryToDecimal(const char* binary);

double fractionalBinaryToDecimal(const char* binary);

%}

%union {

char* str;

double dval;

%token <str> BINARY

%type <dval> expr int_part frac_part

%%

expr:

int_part frac_part { $$ = $1 + $2; printf("Decimal: %lf\n", $$); }

int_part:

BINARY { $$ = binaryToDecimal($1); }

frac_part:
'.' BINARY { $$ = fractionalBinaryToDecimal($2); }

| { $$ = 0; }

%%

double binaryToDecimal(const char* binary) {

double result = 0;

for (int i = 0; i < strlen(binary); i++) {

result = result * 2 + (binary[i] - '0');

return result;

double fractionalBinaryToDecimal(const char* binary) {

double result = 0, factor = 0.5;

for (int i = 0; i < strlen(binary); i++) {

result += (binary[i] - '0') * factor;

factor /= 2;

return result;

int main() {
printf("Enter a binary number: ");

yyparse();

return 0;

void yyerror(const char *s) {

fprintf(stderr, "Error: %s\n", s);

Output :

$ ./binary_parser

Enter a binary number: 101.101

Decimal: 5.625

You might also like