0% found this document useful (0 votes)
13 views51 pages

LP Practical File 21dit044

The document outlines practical exercises for programming in C, focusing on generating various code types (preprocessed, assembly, object, executable) and implementing lexical analyzers using Lex/Flex. It includes examples of macros, transition tables, and token classification, with a strong emphasis on understanding the compilation process and lexical analysis. Learning outcomes highlight the importance of these concepts in software development and debugging.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
13 views51 pages

LP Practical File 21dit044

The document outlines practical exercises for programming in C, focusing on generating various code types (preprocessed, assembly, object, executable) and implementing lexical analyzers using Lex/Flex. It includes examples of macros, transition tables, and token classification, with a strong emphasis on understanding the compilation process and lexical analysis. Learning outcomes highlight the importance of these concepts in software development and debugging.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 51

21DIT044 IT451: LP

PRACTICAL: 1
AIM:
Write a ‘C’ program and generate the following codes for the program.

1. Preprocessed code

2. Assembly Code

3. Object Code

4. Executable Code

THEORY:
1. The C preprocessor modifies the code by expanding macros and including headers before
compilation.

2. Assembly code converts high-level code into machine-specific instructions using mnemonics
like MOV and ADD.

3. Object code is generated after compilation, containing machine-level instructions, typically in


.obj or .o files.

4. Executable code integrates object files and libraries into a program that can run independently
on the system.

5. Each code stage offers insights: preprocessed code simplifies, assembly optimizes, and
executables finalize software usability.

CODE:
Writing a simple C code program:

// File: example.c

#include <stdio.h>

int main() {

int num = 5;

printf("The number is: %d\n", num);

DEPSTAR-IT Page 1
21DIT044 IT451: LP

return 0;

1: Generating the Preprocessed Code

gcc -E example.c -o example.i

2: Generating the Assembly Code

gcc -S example.c –o example.s

3: Generating the Object Code

gcc -c example.c -o example.o

4: Generating the Executable Code:

gcc example.c -o example

./ example

OUTPUT :
Preprocessed Code :

DEPSTAR-IT Page 2
21DIT044 IT451: LP

Assembly Code :

DEPSTAR-IT Page 3
21DIT044 IT451: LP

Object Code :

Executable Code :

DEPSTAR-IT Page 4
21DIT044 IT451: LP

LATEST APPLICATIONS:
Turbo c++, Codeblocks.

LEARNING OUTCOME:
Understanding the flow from preprocessed code to executables helps develop, debug, and optimize
programs, ensuring efficient and correct compilation of C code.

REFERENCE:
1. https://www.geeksforgeeks.org/compiling-a-c-program-behind-the-scenes/

PRACTICAL: 2

DEPSTAR-IT Page 5
21DIT044 IT451: LP

AIM:
Use Macro features of C language and demonstrate the following types of macro with example.

1) Simple Macro 2) Macro with Argument 3) Nested Macro

THEORY:
1. Simple macros define constants or simple text replacements using the #define directive without
parameters.

2. Macros with arguments accept inputs, similar to functions, providing flexibility in code
replacement.

3. Nested macros are macros within other macros, creating complex substitutions during
preprocessing.

4. Macros offer improved performance by reducing function call overhead, but can increase
debugging difficulty.

5. Proper use of macros enhances code readability and reuse but requires careful handling to avoid
side effects.

Code:
1) Simple Macro

#include <stdio.h>

#define PI 3.14159 // Simple macro

int main() {

printf("The value of PI is: %f\n", PI);

return 0;

2) Macro with Argument

#include <stdio.h>

DEPSTAR-IT Page 6
21DIT044 IT451: LP

#define SQUARE(x) ((x) * (x)) // Macro with argument

int main() {

int num = 5;

printf("The square of %d is: %d\n", num, SQUARE(num));

return 0;

3) Nested Macro

#include <stdio.h>

#define ADD(x, y) ((x) + (y)) // First macro

#define MULTIPLY(a, b) ((a) * (b)) // Second macro

#define NESTED_OPERATION(x, y) ADD(MULTIPLY(x, y), y) // Nested macro

int main() {

int a = 3, b = 4;

printf("Nested operation result: %d\n", NESTED_OPERATION(a, b));

return 0;

OUTPUT:
1) Simple Macro

DEPSTAR-IT Page 7
21DIT044 IT451: LP

2) Macro with Argument

3) Nested Macro

LATEST APPLICATIONS:
CodeBlocks, Turbo C++, Visual Studio Code.

LEARNING OUTCOME:
This exercise strengthens understanding of how macros work, demonstrating simple, parameterized,
and nested macros to enhance code modularity and efficiency.

Reference :
https://www.geeksforgeeks.org/macros-and-its-types-in-c-cpp/

DEPSTAR-IT Page 8
21DIT044 IT451: LP

PRACTICAL: 3
AIM:
Write a Lexical Analyzer using Lex or Flex utility of UNIX for following:

1. A lexer to print out all numbers from a given file.

2. A lexer which classifies tokens as words, numbers or "other".

3. Write a Lex Program to count number of vowels and consonants.

4. A lexer which adds line numbers to the given file.

5. A lexer which attempt to extract only comments.

6. A lexer to do word count function of wc command in UNIX.It prints the number of lines, words and
characters in a file.

THEORY:

1. Lexical analyzers scan input text and break it into meaningful tokens for further processing.

2. Lex/Flex utilities generate C programs from lexer specifications using regular expressions for
pattern matching.

3. A lexer can classify tokens into categories such as words, numbers, or symbols based on the
input rules.

4. Lexers are useful for counting and tracking characters, words, lines, and even extracting specific
elements like comments.

5. Lex automates repetitive tasks in compilers, interpreters, or command-line tools through


pattern-based tokenization.

CODE:

1. A lexer to print out all numbers from a given file.

%{

#include <stdio.h>

%}

%option noyywrap

DEPSTAR-IT Page 9
21DIT044 IT451: LP

%%

[0-9]+ { printf("Number: %s\n", yytext); }

.|\n { /* Ignore other characters */ }

%%

int main() {

yylex();

return 0;

2. A lexer which classifies tokens as words, numbers or "other".

%{

#include <stdio.h>

%}

%%

[0-9]+ { printf("Number: %s\n", yytext); }

[a-zA-Z]+ { printf("Word: %s\n", yytext); }

.|\n { printf("Other: %s\n", yytext); }

%%

int main() {

yylex();

return 0;

3. Write a Lex Program to count number of vowels and consonants.

%{

DEPSTAR-IT Page 10
21DIT044 IT451: LP

#include <stdio.h>

int vowels = 0, consonants = 0;

%}

%option noyywrap

%%

[aeiouAEIOU] { vowels++; }

[a-zA-Z] { consonants++; }

.|\n { /* Ignore other characters */ }

%%

int main() {

yylex();

printf("Vowels: %d, Consonants: %d\n", vowels, consonants);

return 0;

4. A lexer which adds line numbers to the given file.

%{

#include <stdio.h>

int line_num = 1;

%}

%option noyywrap

%%

^.*\n { printf("%d: %s", line_num++, yytext); }

%%

DEPSTAR-IT Page 11
21DIT044 IT451: LP

int main() {

yylex();

return 0;

5. A lexer which attempt to extract only comments.

%{

#include <stdio.h>

%}

%option noyywrap

%%

"//".* { printf("Single-line comment: %s\n", yytext); }

"/*"([^*]|\*+[^*/])*\*+"/" { printf("Multi-line comment: %s\n", yytext); }

.|\n { /* Ignore other characters */ }

%%

int main() {

yylex();

return 0;

6. A lexer to do word count function of wc command in UNIX.It prints the number of lines, words and
characters in a file.

%{

DEPSTAR-IT Page 12
21DIT044 IT451: LP

#include <stdio.h>

int lines = 0, words = 0, characters = 0;

%}

%option noyywrap

%%

\n { lines++; characters++; }

[^ \t\n]+ { words++; characters += yyleng; }

. { characters++; }

%%

int main() {

yylex();

printf("Lines: %d, Words: %d, Characters: %d\n", lines, words, characters);

return 0;

OUTPUT:

1. A lexer to print out all numbers from a given file.

DEPSTAR-IT Page 13
21DIT044 IT451: LP

2. A lexer which classifies tokens as words, numbers or "other".

3. Write a Lex Program to count number of vowels and consonants.

4. A lexer which adds line numbers to the given file.

DEPSTAR-IT Page 14
21DIT044 IT451: LP

5. A lexer which attempt to extract only comments.

6. A lexer to do word count function of wc command in UNIX.It prints the number of lines, words and
characters in a file.

DEPSTAR-IT Page 15
21DIT044 IT451: LP

Latest Application:

Flex, bison,Codeblocks.

Learning Outcome:

Implementing lexical analyzers using Lex/Flex enhances understanding of token classification, text
processing, and pattern matching in UNIX-based utilities.

Reference:
https://www.geeksforgeeks.org/flex-fast-lexical-analyzer-generator/

PRACTICAL: 4

DEPSTAR-IT Page 16
21DIT044 IT451: LP

AIM:

Implement Lexical analyzer for C language using lex.

THEORY:

1. A lexical analyzer scans C code to break it into tokens like keywords, identifiers, numbers, and
symbols.

2. Lex utility uses pattern rules to generate a C program that performs lexical analysis.

3. Regular expressions define patterns in Lex to identify different token types.

4. Lex automatically discards spaces and newlines unless specified for tokenization.

5. The generated lexer simplifies subsequent parsing stages by classifying tokens efficiently.

CODE:

c_lexer.l file code:

%{

#include <stdio.h>

#include <stdlib.h>

%}

/* Define tokens */

%option noyywrap

%%

"int"|"float"|"double"|"char"|"void" { printf("Keyword: %s\n", yytext); }

[0-9]+ { printf("Integer Constant: %s\n", yytext); }

\"([^\\"]|\\.)*\" { printf("String Constant: %s\n", yytext); }

[a-zA-Z_][a-zA-Z0-9_]* { printf("Identifier: %s\n", yytext); }

DEPSTAR-IT Page 17
21DIT044 IT451: LP

"=="|"!="|"<="|">="|"<"|">"|"\+"|"-"|"*"|"/"|"=" { printf("Operator: %s\n", yytext); }

"{"|"{"|"}"|"(" | ")"|"[" | "]" | ";" | "," | "." { printf("Symbol: %s\n", yytext); }

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

"//".* { printf("Single-line Comment: %s\n", yytext); }

"/*".* "*/" { printf("Multi-line Comment: %s\n", yytext); }

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

%%

int main(int argc, char **argv) {

yylex(); // Call the lexical analyzer

return 0;

void yyerror(const char *s) {

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

#define SQUARE(x) ((x) * (x)) // Macro with Argument

int main() {

int num = 5;

printf("Square of %d is: %d\n", num, SQUARE(num));

return 0;

DEPSTAR-IT Page 18
21DIT044 IT451: LP

nested macro

#include <stdio.h>

#define MAX(a, b) ((a) > (b) ? (a) : (b)) // Macro with Argument

#define MAX_SQUARE(a, b) SQUARE(MAX(a, b)) // Nested Macro

#define SQUARE(x) ((x) * (x)) // Another Macro with Argument

int main() {

int x = 4, y = 7;

printf("The square of the larger number between %d and %d is: %d\n", x, y, MAX_SQUARE(x, y));

return 0;

OUTPUT:

Simple Macro

DEPSTAR-IT Page 19
21DIT044 IT451: LP

Latest Application:

Flex, bison,Codeblocks.

Learning Outcome:

This task deepens understanding of Lex-based lexical analysis for C, helping process tokens like
keywords, numbers, and symbols in a systematic way.

Reference:
https://www.geeksforgeeks.org/introduction-of-lexical-analysis/

DEPSTAR-IT Page 20
21DIT044 IT451: LP

PRACTICAL: 5
AIM:

Write a program which enters Transition Table, accepting state and input string as input and checks
whether the given string is accepted or not.

Theory:
1. The transition table implementation is a practical exercise in finite automata theory, where
users can input a state, transitions, and an input string.
2. The program checks whether the given string is accepted based on the defined transition
rules.
3. Each transition is defined by a combination of a current state, an input symbol, and the
next state.
4. This allows the simulation of a finite state machine, providing insights into automata
theory and the principles of language recognition.

CODE:
#include <stdio.h>

#include <string.h>

#define MAX_STATES 10

#define MAX_SYMBOLS 10

typedef struct {

char state[MAX_STATES][MAX_SYMBOLS]; // States

int transition[MAX_STATES][MAX_SYMBOLS]; // Transition table

int num_states; // Number of states

int num_symbols; // Number of symbols

int start_state; // Starting state

DEPSTAR-IT Page 21
21DIT044 IT451: LP

int accept_states[MAX_STATES]; // Accepting states

int num_accept_states; // Number of accepting states

} DFA;

// Function to initialize the DFA

void initDFA(DFA *dfa) {

dfa->num_states = 0;

dfa->num_symbols = 0;

dfa->num_accept_states = 0;

// Function to add a state to the DFA

void addState(DFA *dfa, const char *state, int is_accept) {

strcpy(dfa->state[dfa->num_states], state);

if (is_accept) {

dfa->accept_states[dfa->num_accept_states++] = dfa->num_states;

dfa->num_states++;

// Function to set the transition for a given state and symbol

void setTransition(DFA *dfa, const char *state, char symbol, const char *next_state) {

int state_index = -1, next_state_index = -1;

for (int i = 0; i < dfa->num_states; i++) {

DEPSTAR-IT Page 22
21DIT044 IT451: LP

if (strcmp(dfa->state[i], state) == 0) {

state_index = i;

if (strcmp(dfa->state[i], next_state) == 0) {

next_state_index = i;

if (state_index != -1 && next_state_index != -1) {

dfa->transition[state_index][symbol - 'a'] = next_state_index; // Assuming 'a' to 'z'

// Function to check if the input string is accepted by the DFA

int isAccepted(DFA *dfa, const char *input_string) {

int current_state = dfa->start_state;

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

char symbol = input_string[i];

if (symbol < 'a' || symbol > 'z') { // Check for valid symbols

return 0; // Invalid symbol

current_state = dfa->transition[current_state][symbol - 'a'];

if (current_state == -1) {

return 0; // Transition not defined

DEPSTAR-IT Page 23
21DIT044 IT451: LP

for (int i = 0; i < dfa->num_accept_states; i++) {

if (current_state == dfa->accept_states[i]) {

return 1; // Accepted

return 0; // Not accepted

int main() {

DFA dfa;

initDFA(&dfa);

// Define states and transitions

addState(&dfa, "q0", 0);

addState(&dfa, "q1", 0);

addState(&dfa, "q2", 1); // Accept state

// Initialize transition table with -1 (no transition)

for (int i = 0; i < MAX_STATES; i++) {

for (int j = 0; j < MAX_SYMBOLS; j++) {

dfa.transition[i][j] = -1;

DEPSTAR-IT Page 24
21DIT044 IT451: LP

// Set transitions: Example transitions for a simple DFA

setTransition(&dfa, "q0", 'a', "q1");

setTransition(&dfa, "q1", 'b', "q2");

// Starting state

dfa.start_state = 0;

// Input string to check

char input_string[100];

printf("Enter the input string: ");

scanf("%s", input_string);

if (isAccepted(&dfa, input_string)) {

printf("Accepted\n");

} else {

printf("Rejected\n");

return 0;

}"=="|"!="|"<="|">="|"<"|">"|"\+"|"-"|"*"|"/"|"=" { printf("Operator: %s\n", yytext); }

"{"|"{"|"}"|"(" | ")"|"[" | "]" | ";" | "," | "." { printf("Symbol: %s\n", yytext); }

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

"//".* { printf("Single-line Comment: %s\n", yytext); }

"/*".* "*/" { printf("Multi-line Comment: %s\n", yytext); }

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

DEPSTAR-IT Page 25
21DIT044 IT451: LP

%%

int main(int argc, char **argv) {

yylex(); // Call the lexical analyzer

return 0;

void yyerror(const char *s) {

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

#define SQUARE(x) ((x) * (x)) // Macro with Argument

int main() {

int num = 5;

printf("Square of %d is: %d\n", num, SQUARE(num));

return 0;

nested macro

#include <stdio.h>

#define MAX(a, b) ((a) > (b) ? (a) : (b)) // Macro with Argument

DEPSTAR-IT Page 26
21DIT044 IT451: LP

#define MAX_SQUARE(a, b) SQUARE(MAX(a, b)) // Nested Macro

#define SQUARE(x) ((x) * (x)) // Another Macro with Argument

int main() {

int x = 4, y = 7;

printf("The square of the larger number between %d and %d is: %d\n", x, y, MAX_SQUARE(x, y));

return 0;

OUTPUT:

Latest Application:

Flex, bison,Codeblocks.

Learning Outcome:
Implementing transition tables aids in understanding how finite automata validate input strings based
on states and transitions.

Reference :
https://www.geeksforgeeks.org/transition-table-in-automata/

DEPSTAR-IT Page 27
21DIT044 IT451: LP

PRACTICAL: 6
AIM:
Explore the JFLAP Tool to demonstrate the deterministic finite automata for following also find its
Regular expression.

1) Odd number of 0’a or Even number of 1’s

2) Odd number of 0’a and Even number of 1’s

Theory:
1. JFLAP is a tool for visualizing and testing automata, grammars, and formal languages.

2. Deterministic Finite Automata (DFA) has one possible transition per input for each state.

3. For odd 0’s or even 1’s, DFA tracks counts of both 0’s and 1’s in different states.

4. For odd 0’s and even 1’s, the DFA ensures both conditions simultaneously through appropriate
state transitions.

5. Regular expressions describe the language accepted by automata, using operators like *, |, and
concatenation.

CODE and OUTPUT:


1) Odd number of 0’a or Even number of 1’s

DEPSTAR-IT Page 28
21DIT044 IT451: LP

2) Odd number of 0’a and Even number of 1’s

Learning Outcome:

DEPSTAR-IT Page 29
21DIT044 IT451: LP

Using JFLAP to create DFA provides hands-on experience with state transitions and constructing
equivalent regular expressions for formal languages.

Latest Application:

Juypiter Notebook.

Reference:

https://www.geeksforgeeks.org/dfa-machines-accepting-odd-number-of-0s-or-and-even-
number-of-1s/

PRACTICAL: 7
AIM:
Create Google Form for the student registration with student ID, Name, Email Address, Mobile number
etc. Provide Regular expression in every field of the Google Form.

Theory:
1.

CODE:
function createStudentRegistrationForm() {

// Create a new form

const form = FormApp.create('Student Registration Form');

// Add Student ID field with validation

const studentIDItem = form.addTextItem().setTitle('Student ID');

studentIDItem.setHelpText('Enter a 7-digit student ID.');

studentIDItem.setValidation(

DEPSTAR-IT Page 30
21DIT044 IT451: LP

FormApp.createTextValidation()

.setHelpText('Student ID must be 7 digits.')

.requireTextMatchesPattern('^\\d{7}$')

.build()

);

// Add Name field with validation

const nameItem = form.addTextItem().setTitle('Full Name');

nameItem.setHelpText('Enter your full name (letters only).');

nameItem.setValidation(

FormApp.createTextValidation()

.setHelpText('Name must contain only letters.')

.requireTextMatchesPattern('^[A-Za-z\\s]+$')

.build()

);

// Add Email field with validation

const emailItem = form.addTextItem().setTitle('Email Address');

emailItem.setHelpText('Enter your valid email address.');

emailItem.setValidation(

FormApp.createTextValidation()

.setHelpText('Invalid email format.')

.requireTextMatchesPattern('^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$')

.build()

);

// Add Mobile Number field with validation

const mobileItem = form.addTextItem().setTitle('Mobile Number');

DEPSTAR-IT Page 31
21DIT044 IT451: LP

mobileItem.setHelpText('Enter your 10-digit mobile number.');

mobileItem.setValidation(

FormApp.createTextValidation()

.setHelpText('Mobile number must be exactly 10 digits.')

.requireTextMatchesPattern('^\\d{10}$')

.build()

);

// Add Date of Birth field

form.addDateItem().setTitle('Date of Birth').setHelpText('Select your date of birth.');

// Log the form URL

Logger.log('Form URL: ' + form.getEditUrl());

OUTPUT:

DEPSTAR-IT Page 32
21DIT044 IT451: LP

Learning Outcome:
This exercise enhances skills in using Google Forms and regex for input validation, ensuring structured
and error-free student data collection.

Latest Application:
Google Form.

DEPSTAR-IT Page 33
21DIT044 IT451: LP

Reference:
https://docs.google.com/forms/d/1Wn0auIzqSvvAxsc6OHAd-c_KWoK5T_o0DB971nu0pTA/edit

PRACTICAL: 8
AIM:
Write Generation Of Three Address Code in C Programming.

Theory:
1. Three-address code (TAC) divides complex statements into simpler instructions with a
maximum of three operands.

2. TAC facilitates efficient code generation, using temporary variables for intermediate results.

3. Common TAC operations include assignment, arithmetic operations, and conditional or


unconditional jumps.

4. This code serves as an intermediate representation for optimization during the compilation
process.

5. C programming can implement TAC by translating complex expressions step by step into
smaller instructions.

CODE:
#include <stdio.h>

#include <stdlib.h>

#include <string.h>

DEPSTAR-IT Page 34
21DIT044 IT451: LP

#include <ctype.h>

int tempVarCount = 0;

// Function to create a new temporary variable name

char* newTemp() {

static char temp[10];

sprintf(temp, "t%d", tempVarCount++);

return temp;

// Function to generate three address code

void generateTAC(char* expression) {

char stack[20][20]; // Stack to store operands

int top = -1; // Stack pointer

printf("Three Address Code:\n");

// Iterate through the expression

for (int i = 0; expression[i] != '\0'; i++) {

if (isalnum(expression[i])) { // If it's an operand

char operand[2] = {expression[i], '\0'};

strcpy(stack[++top], operand); // Push operand onto stack

} else if (expression[i] == '+' || expression[i] == '-' ||

expression[i] == '*' || expression[i] == '/') { // If it's an operator

char op2[20], op1[20];

strcpy(op2, stack[top--]); // Pop two operands

strcpy(op1, stack[top--]);

DEPSTAR-IT Page 35
21DIT044 IT451: LP

// Generate TAC for the operation

char* tempVar = newTemp();

printf("%s = %s %c %s\n", tempVar, op1, expression[i], op2);

// Push the result back onto the stack

strcpy(stack[++top], tempVar);

// Final result

printf("Result: %s\n", stack[top]);

int main() {

char expression[100];

printf("Enter an arithmetic expression: ");

scanf("%s", expression); // Read input expression

generateTAC(expression); // Generate TAC for the expression

return 0;

OUTPUT:

DEPSTAR-IT Page 36
21DIT044 IT451: LP

Learning Outcome:

This task strengthens understanding of intermediate code generation and compiler


processes for efficient program execution.

Latest Application:
CodeBlocks.

Reference:
https://www.geeksforgeeks.org/three-address-code-compiler/

DEPSTAR-IT Page 37
21DIT044 IT451: LP

PRACTICAL: 9
AIM:
Write program to implement Recursive Descent Parser for the given grammar.

E -> T + E | T

T -> F * T | F

F -> id

Theory:
1. A recursive descent parser uses a set of recursive procedures to process input based on
grammar rules.

2. The parser matches tokens from the input string with the grammar rules, building a parse tree.

3. Each non-terminal in the grammar has a corresponding function that attempts to match its
production.

4. Backtracking may occur if the parser encounters a mismatch, allowing exploration of


alternative parsing paths.

DEPSTAR-IT Page 38
21DIT044 IT451: LP

5. This parsing technique is straightforward but may struggle with left recursion and ambiguity in
grammar.

CODE:
#include <stdio.h>

#include <string.h>

#define SUCCESS 1

#define FAILED 0

// Function prototypes

int E(), Edash(), T(), Tdash(), F();

const char *cursor;

char string[64];

int main() {

puts("Enter the string");

scanf("%s", string); // Read input from the user

cursor = string;

puts("");

puts("Input Action");

puts("--------------------------------");

// Call the starting non-terminal E

if (E() && *cursor == '\0') { // If parsing is successful and the cursor has reached the end

puts("--------------------------------");

puts("String is successfully parsed");

DEPSTAR-IT Page 39
21DIT044 IT451: LP

return 0;

else {

puts("--------------------------------");

puts("Error in parsing String");

return 1;

// Grammar rule: E -> T E'

int E() {

printf("%-16s E -> T E'\n", cursor);

if (T()) { // Call non-terminal T

if (Edash()) // Call non-terminal E'

return SUCCESS;

else

return FAILED;

else

return FAILED;

// Grammar rule: E' -> + T E' | $

int Edash() {

if (*cursor == '+') {

printf("%-16s E' -> + T E'\n", cursor);

cursor++;

if (T()) { // Call non-terminal T

DEPSTAR-IT Page 40
21DIT044 IT451: LP

if (Edash()) // Call non-terminal E'

return SUCCESS;

else

return FAILED;

else

return FAILED;

else {

printf("%-16s E' -> $\n", cursor);

return SUCCESS;

// Grammar rule: T -> F T'

int T() {

printf("%-16s T -> F T'\n", cursor);

if (F()) { // Call non-terminal F

if (Tdash()) // Call non-terminal T'

return SUCCESS;

else

return FAILED;

else

return FAILED;

// Grammar rule: T' -> * F T' | $

DEPSTAR-IT Page 41
21DIT044 IT451: LP

int Tdash() {

if (*cursor == '*') {

printf("%-16s T' -> * F T'\n", cursor);

cursor++;

if (F()) { // Call non-terminal F

if (Tdash()) // Call non-terminal T'

return SUCCESS;

else

return FAILED;

else

return FAILED;

else {

printf("%-16s T' -> $\n", cursor);

return SUCCESS;

// Grammar rule: F -> ( E ) | i

int F() {

if (*cursor == '(') {

printf("%-16s F -> ( E )\n", cursor);

cursor++;

if (E()) { // Call non-terminal E

if (*cursor == ')') {

cursor++;

return SUCCESS;

DEPSTAR-IT Page 42
21DIT044 IT451: LP

else

return FAILED;

else

return FAILED;

else if (*cursor == 'i') {

printf("%-16s F -> i\n", cursor);

cursor++;

return SUCCESS;

else

return FAILED;

OUTPUT:

DEPSTAR-IT Page 43
21DIT044 IT451: LP

Learning Outcome:

Implementing a recursive descent parser helps in understanding how to analyze and


process structured input based on defined grammar rules.

Latest Application:
CodeBlocks.

Reference:
https://www.geeksforgeeks.org/recursive-descent-parser/

PRACTICAL: 10

DEPSTAR-IT Page 44
21DIT044 IT451: LP

AIM:
Demonstrate the parsing technique using ANTLR Tool.

Theory:
1. ANTLR (Another Tool for Language Recognition) is a powerful parser generator that uses a
grammar file to define language syntax.

2. ANTLR generates parsers, lexers, and tree walkers from defined grammars, streamlining
language processing tasks.

3. It supports various output languages, including Java, C#, Python, and JavaScript, making it
versatile for different applications.

4. ANTLR's ability to handle complex grammars allows for efficient parsing of programming
languages and domain-specific languages.

5. The tool generates Abstract Syntax Trees (ASTs), enabling further processing and analysis of
parsed code.

CODE and OUTPUT:


For “100 + 4 * 7”

DEPSTAR-IT Page 45
21DIT044 IT451: LP

Learning Outcome:

Using ANTLR to demonstrate parsing techniques enhances understanding of grammar


definition and automatic parser generation for structured language processing.

Latest Application:

ANTLR.

Reference:
https://tomassetti.me/antlr-mega-tutorial/

DEPSTAR-IT Page 46
21DIT044 IT451: LP

PRACTICAL: 11
AIM:
Write a Parser using YACC or utility of UNIX for following: Write a Program for a simple desk
calculator using YACC Specification.

Theory:
1. YACC (Yet Another Compiler Compiler) generates parsers based on a specified grammar for
language processing tasks.

2. A simple desk calculator can be designed using YACC to evaluate arithmetic expressions and
manage operator precedence.

3. YACC uses production rules to define grammar, with actions specified in C to perform
calculations.

4. Lexical analysis can be integrated with YACC for tokenizing input using regular expressions.

5. Error handling is essential to manage invalid expressions gracefully, providing user feedback.

CODE:

Code for lax file:


%{

#include "y.tab.h"

%}

%%

// Define tokens

[0-9]+ { yylval = atoi(yytext); return NUMBER; }

[+] { return PLUS; }

[-] { return MINUS; }

[*] { return MULTIPLY; }

DEPSTAR-IT Page 47
21DIT044 IT451: LP

[/] { return DIVIDE; }

\n { return NEWLINE; }

[ \t] { /* ignore whitespace */ }

%%

// Error handling

int yywrap() {

return 1;

Code for yacc file:


%{

#include <stdio.h>

#include <stdlib.h>

// Function prototypes

int yylex();

void yyerror(const char *s);

%}

%token NUMBER

%token PLUS MINUS MULTIPLY DIVIDE

%token NEWLINE

%%

// Define grammar rules

DEPSTAR-IT Page 48
21DIT044 IT451: LP

calculation:

| calculation line

line:

expression NEWLINE {

printf("Result: %d\n", $1);

expression:

expression PLUS term {

$$ = $1 + $3;

| expression MINUS term {

$$ = $1 - $3;

| term {

$$ = $1;

term:

term MULTIPLY factor {

$$ = $1 * $3;

| term DIVIDE factor {

$$ = $1 / $3;

DEPSTAR-IT Page 49
21DIT044 IT451: LP

| factor {

$$ = $1;

factor:

NUMBER {

$$ = $1;

%%

// Error handling function

void yyerror(const char *s) {

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

int main() {

printf("Simple Desk Calculator. Type 'exit' to quit.\n");

return yyparse();

DEPSTAR-IT Page 50
21DIT044 IT451: LP

OUTPUT:

Learning Outcome:

Implementing a desk calculator using YACC enhances understanding of parser


generation and expression evaluation through formal grammar definitions.

Latest Application:
CodeBlocks.

Reference:
https://www.geeksforgeeks.org/introduction-to-yacc/

DEPSTAR-IT Page 51

You might also like