0% found this document useful (0 votes)
9 views

CD C Programs

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)
9 views

CD C Programs

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/ 12

1a

lexical analyzer:

#include <stdio.h>
#include <ctype.h>
#include <string.h>

#define MAX 100

// Check if a token is a keyword


int isKeyword(const char *token) {
const char *keywords[] = {"if", "else", "while", "int", "return"};
for (int i = 0; i < 5; i++) {
if (strcmp(token, keywords[i]) == 0) return 1;
}
return 0;
}

// Identify the type of token


void identifyToken(char *token) {
if (isKeyword(token)) {
printf("Keyword: %s\n", token);
} else if (isalpha(token[0]) || token[0] == '_') {
printf("Identifier: %s\n", token);
} else if (isdigit(token[0])) {
printf("Constant: %s\n", token);
} else {
printf("Unknown token: %s\n", token);
}
}

// Analyze the line and classify tokens


void analyzeLine(const char *line) {
char token[MAX];
int i = 0, j = 0;
while (line[i] != '\0') {
if (isalnum(line[i]) || line[i] == '_') {
token[j++] = line[i++];
} else {
if (j > 0) {
token[j] = '\0';
identifyToken(token);
j = 0;
}
if (line[i] == '/' && line[i + 1] == '/') {
printf("Comment: %s\n", &line[i]);
break;
} else if (ispunct(line[i])) {
printf("Operator: %c\n", line[i]);
}
i++;
}
}
if (j > 0) { // Handle the last token if any
token[j] = '\0';
identifyToken(token);
}
}

int main() {
char input[MAX];
printf("Enter a line of code: ");
fgets(input, MAX, stdin);
analyzeLine(input);
return 0;
}

Key Improvements:

1. Removed Duplicate Loops:


o The identifyToken function no longer contains redundant loops for constants
and identifiers.
o Replaced them with simpler checks.
2. Combined Functionality:
o A helper function isKeyword is used for keyword checking.
3. Token Handling:
o Tokens are collected in a buffer as characters are processed. When a delimiter is
found, the token is classified and printed.
4. Operator and Comment Handling:
o Inline handling of operators and comments is simplified.
5. Reduced Conditionals:
o Simplified token type checks (e.g., no inner loops for constants and identifiers).

Sample Run:

Input:

int a = 10; // Initialize

Output:

Keyword: int
Identifier: a
Operator: =
Constant: 10
Comment: // Initialize

This version retains functionality while being shorter and more readable.

1b.

Here's a simplified C program for the implementation of a Symbol Table. This program uses an
array to store symbols and their associated information, and allows basic operations like insertion
and display.
#include <stdio.h>
#include <string.h>

#define MAX 100

typedef struct {
char name[50];
char type[20];
int size;
} Symbol;

Symbol symbolTable[MAX];
int symbolCount = 0;

// Insert a symbol into the symbol table


void insertSymbol(char *name, char *type, int size) {
for (int i = 0; i < symbolCount; i++) {
if (strcmp(symbolTable[i].name, name) == 0) {
printf("Symbol '%s' already exists in the table.\n", name);
return;
}
}
strcpy(symbolTable[symbolCount].name, name);
strcpy(symbolTable[symbolCount].type, type);
symbolTable[symbolCount].size = size;
symbolCount++;
printf("Symbol '%s' added successfully.\n", name);
}

// Display the symbol table


void displaySymbolTable() {
printf("\nSymbol Table:\n");
printf("Name\tType\tSize\n");
printf("-----------------------\n");
for (int i = 0; i < symbolCount; i++) {
printf("%s\t%s\t%d\n", symbolTable[i].name, symbolTable[i].type,
symbolTable[i].size);
}
if (symbolCount == 0) {
printf("No symbols in the table.\n");
}
}

int main() {
int choice;
char name[50], type[20];
int size;

do {
printf("\n1. Insert Symbol\n2. Display Symbol Table\n3. Exit\n");
printf("Enter your choice: ");
scanf("%d", &choice);
switch (choice) {
case 1:
printf("Enter symbol name: ");
scanf("%s", name);
printf("Enter symbol type: ");
scanf("%s", type);
printf("Enter symbol size: ");
scanf("%d", &size);
insertSymbol(name, type, size);
break;
case 2:
displaySymbolTable();
break;
case 3:
printf("Exiting program.\n");
break;
default:
printf("Invalid choice! Please try again.\n");
}
} while (choice != 3);

return 0;
}

Explanation:

1. Symbol Table Structure:


o Each symbol has a name, type, and size.
o An array symbolTable stores the symbols, and symbolCount tracks the number
of symbols.
2. Operations:
o Insert Symbol:
 Adds a new symbol if it doesn't already exist in the table.
 Checks for duplicates by comparing symbol names.
o Display Symbol Table:
 Prints all stored symbols in tabular format.
3. Menu-Driven Interface:
o Provides options to insert symbols, display the table, or exit.

Sample Run:

Input:

1
Enter symbol name: x
Enter symbol type: int
Enter symbol size: 4

1
Enter symbol name: y
Enter symbol type: float
Enter symbol size: 8

2
Output:

Symbol 'x' added successfully.


Symbol 'y' added successfully.

Symbol Table:
Name Type Size
-----------------------
x int 4
y float 8

This implementation is simple and demonstrates the concept of a symbol table effectively.

1c:Symbol Table for different operation

Here’s a simplified and short C program for a Symbol Table that supports basic operations like
Insert, Search, and Display.

Short C Program:
#include <stdio.h>
#include <string.h>

#define MAX 100

typedef struct {
char name[50], type[20];
int size;
} Symbol;

Symbol symbolTable[MAX];
int symbolCount = 0;

// Insert a symbol into the table


void insertSymbol(char *name, char *type, int size) {
for (int i = 0; i < symbolCount; i++) {
if (!strcmp(symbolTable[i].name, name)) {
printf("Symbol '%s' already exists.\n", name);
return;
}
}
strcpy(symbolTable[symbolCount].name, name);
strcpy(symbolTable[symbolCount].type, type);
symbolTable[symbolCount++].size = size;
printf("Symbol '%s' added.\n", name);
}

// Search for a symbol in the table


void searchSymbol(char *name) {
for (int i = 0; i < symbolCount; i++) {
if (!strcmp(symbolTable[i].name, name)) {
printf("Found: %s, Type: %s, Size: %d\n", symbolTable[i].name,
symbolTable[i].type, symbolTable[i].size);
return;
}
}
printf("Symbol '%s' not found.\n", name);
}

// Display the symbol table


void displaySymbolTable() {
printf("\nSymbol Table:\nName\tType\tSize\n-----------------------\n");
for (int i = 0; i < symbolCount; i++)
printf("%s\t%s\t%d\n", symbolTable[i].name, symbolTable[i].type,
symbolTable[i].size);
if (!symbolCount) printf("No symbols in the table.\n");
}

int main() {
char name[50], type[20];
int size, choice;

while (1) {
printf("\n1. Insert Symbol\n2. Search Symbol\n3. Display Symbol
Table\n4. Exit\nChoice: ");
scanf("%d", &choice);
if (choice == 4) break;
if (choice == 1) {
printf("Enter name, type, size: ");
scanf("%s %s %d", name, type, &size);
insertSymbol(name, type, size);
} else if (choice == 2) {
printf("Enter symbol name to search: ");
scanf("%s", name);
searchSymbol(name);
} else if (choice == 3) {
displaySymbolTable();
} else {
printf("Invalid choice!\n");
}
}
return 0;
}

Features:

1. Insert:
o Adds a new symbol if it doesn't exist.
o Checks for duplicate entries.
2. Search:
o Looks up a symbol by name and displays its details if found.
3. Display:
o Shows all symbols in a tabular format.
4. Menu-Driven Interface:
o Allows user to select operations interactively.

Sample Run:
Input:

1
x int 4
1
y float 8
2
x
3
4

Output:

Symbol 'x' added.


Symbol 'y' added.
Found: x, Type: int, Size: 4

Symbol Table:
Name Type Size
-----------------------
x int 4
y float 8

This short program effectively demonstrates multiple symbol table operations while keeping the
implementation simple and concise.

4b:Program to Construct LL(1) Parser

Here’s a very short and simplified C program to construct an LL(1) Parser. This example
assumes a basic grammar, such as:

S -> aA
A -> b | ε

Short LL(1) Parser Program:


#include <stdio.h>
#include <string.h>

char input[100];
int pos = 0;

// Function prototypes
void S();
void A();

void S() {
if (input[pos] == 'a') {
pos++;
A();
} else {
printf("Error: Expected 'a'\n");
}
}

void A() {
if (input[pos] == 'b') {
pos++;
} else if (input[pos] == '\0') {
// ε (epsilon) production, do nothing
return;
} else {
printf("Error: Expected 'b' or ε\n");
}
}

int main() {
printf("Enter input string: ");
scanf("%s", input);

S(); // Start parsing from the start symbol

if (input[pos] == '\0') {
printf("Input string is accepted.\n");
} else {
printf("Error: Unexpected characters at end of input.\n");
}

return 0;
}

Explanation:

1. Grammar:
o The grammar used is:
o S -> aA
o A -> b | ε
o It accepts strings like a, ab.
2. Structure:
o S() and A() functions represent the non-terminals S and A in the grammar.
o The pos variable tracks the current position in the input string.
3. Parser Workflow:
o The S() function ensures the input starts with a and then calls A().
o The A() function checks for b or epsilon (represented by the end of the string).
4. Error Handling:
o Prints an error message if the input doesn't match the expected production.
5. Acceptance:
o If the parser finishes and reaches the end of the string (\0), the input is accepted.
Sample Run:

Input:

ab

Output:

Input string is accepted.

Input:

aa

Output:

Error: Unexpected characters at end of input.

This simple program demonstrates an LL(1) parser for a basic grammar in a compact way.

6.Code Optimization Techniques


Here's a short and simplified C program demonstrating basic code optimization techniques like
constant folding, dead code elimination, and strength reduction.

Program:
#include <stdio.h>

void constantFolding() {
int x = 5 * 10; // Constant Folding
printf("Constant Folding Result: %d\n", x);
}

void deadCodeElimination() {
int a = 10, b = 20;
if (a < b) {
printf("Dead Code Eliminated: a < b\n");
}
// The following code is unreachable and removed during optimization
// printf("This line is dead code\n");
}

void strengthReduction() {
int x = 8;
int y = x * 2; // Before Optimization
int z = x << 1; // After Optimization (Strength Reduction)
printf("Strength Reduction: %d (Before: %d, Optimized: %d)\n", x, y, z);
}

int main() {
constantFolding();
deadCodeElimination();
strengthReduction();
return 0;
}

Key Techniques:

1. Constant Folding:
o Evaluate constant expressions at compile time.
o Example: 5 * 10 is precomputed to 50.
2. Dead Code Elimination:
o Remove code that will never be executed.
o Example: Unreachable printf statement removed.
3. Strength Reduction:
o Replace expensive operations (e.g., multiplication) with cheaper ones (e.g., bit
shifts).
o Example: x * 2 optimized to x << 1.

Output:
Constant Folding Result: 50
Dead Code Eliminated: a < b
Strength Reduction: 8 (Before: 16, Optimized: 16)

This short program provides a simple illustration of common code optimization techniques in C.

7.Intermediate to Assembly Code generation


Here’s a short and simplified C program to demonstrate Intermediate to Assembly Code
generation. The program uses basic arithmetic expressions as input and generates equivalent
simplified assembly-like instructions.

C Program:
#include <stdio.h>
#include <string.h>

void generateAssembly(char *expression) {


char var1 = expression[0]; // Left-hand variable
char op = expression[2]; // Operator
char var2 = expression[4]; // First operand
char var3 = expression[6]; // Second operand

printf("; Assembly Code for %s\n", expression);


printf("MOV R0, %c ; Load %c into R0\n", var2, var2);
if (op == '+') {
printf("ADD R0, %c ; Add %c to R0\n", var3, var3);
} else if (op == '-') {
printf("SUB R0, %c ; Subtract %c from R0\n", var3, var3);
} else if (op == '*') {
printf("MUL R0, %c ; Multiply R0 by %c\n", var3, var3);
} else if (op == '/') {
printf("DIV R0, %c ; Divide R0 by %c\n", var3, var3);
}
printf("MOV %c, R0 ; Store result in %c\n", var1, var1);
}

int main() {
char expression[20];
printf("Enter a simple expression (e.g., a = b + c): ");
scanf("%[^\n]%*c", expression);

generateAssembly(expression);
return 0;
}

Input Format:

 Expression: A simple assignment operation like a = b + c.

Example Run:

Input:

a = b + c

Output:

; Assembly Code for a = b + c


MOV R0, b ; Load b into R0
ADD R0, c ; Add c to R0
MOV a, R0 ; Store result in a

Input:

x = y * z

Output:

; Assembly Code for x = y * z


MOV R0, y ; Load y into R0
MUL R0, z ; Multiply R0 by z
MOV x, R0 ; Store result in x
Explanation:

1. Input Parsing:
o Assumes the input is in the form a = b op c, where op can be +, -, *, or /.
2. Assembly Generation:
o Uses MOV to load and store values.
o Uses basic instructions (ADD, SUB, MUL, DIV) for operations.
3. Output:
o The assembly-like code is printed for the given expression.

This program provides a simple way to demonstrate the concept of intermediate to assembly
code translation for arithmetic expressions.

You might also like