compiler Satyam
compiler Satyam
A
Lab Record
Compiler Design
Lab (BCSP-602)
Session: - 2023-24
Department of Computer Science and Engineering
Submitted to Submitted by
Mrs Ritu Pal Satyam Jain
(210120101102) Assistant professor
INDEX
Teacher’s Remark
S. no. Experiment Name Date
Signature
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
EXPERIMENT- 1
OBJECTIVE:
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.
PROGRAM:
#include <stdio.h>
#include <stdlib.h>
#include
<string.h>
#include <ctype.h>
#define MAX_IDENTIFIER_LENGTH 50
// Token types
typedef enum {
TOKEN_IDENTIFIER,
TOKEN_INTEGER,
TOKEN_PLUS,
TOKEN_MINUS,
TOKEN_MULTIPLY,
TOKEN_DIVIDE,
TOKEN_ASSIGN,
TOKEN_SEMICOLON,
TOKEN_OPEN_PAREN,
TOKEN_CLOSE_PAREN,
TOKEN_END_OF_INPUT
} TokenType;
// Token structure
typedef struct {
TokenType type;
char value[MAX_IDENTIFIER_LENGTH + 1]; // +1 for null terminator
} Token;
// Function prototypes
void get_next_token(Token *token, FILE *fp);
void skip_whitespace_and_comments(FILE *fp);
int main() {
FILE *fp;
Token token;
// Close file
fclose(fp);
return EXIT_SUCCESS;
}
void get_next_token(Token *token, FILE *fp) {
char c;
int i = 0;
// End of input
token->type = TOKEN_END_OF_INPUT;
}
PROGRAM:
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
int main() {
char line[100];
printf("Enter a line: ");
fgets(line, sizeof(line),
stdin); if (is_comment(line))
{
printf("The line is a comment.\n");
} else {
printf("The line is not a comment.\n");
}
return 0;
}
Output
EXPERIMENT-3
OBJECTIVE:
PROGRAM:
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
int main() {
char str[100];
OBJECTIVE:
Write a C program to test whether a given identifier is valid or not
PROGRAM:
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <ctype.h>
return true;
}
int main() {
char identifier[100];
printf("Enter an identifier:
"); scanf("%s", identifier);
if (isValidIdentifier(identifier)) {
printf("'%s' is a valid identifier.\n", identifier);
} else {
printf("'%s' is not a valid identifier.\n", identifier);
}
Output
return 0;
}
EXPERIMENT-5
OBJECTIVE:
PROGRAM:
#include <stdio.h>
#include <stdbool.h>
#include <ctype.h>
int main() {
char ch;
printf("Enter an operator:
"); scanf(" %c", &ch);
if (isValidOperator(ch)) {
printf("'%c' is a valid operator.\n", ch);
} else {
printf("'%c' is not a valid operator.\n", ch);
}
Output
return
}
EXPERIMENT-6
OBJECTIVE:
Implement the lexical analyzer using JLex, flex or other lexical analyzer generating tools.
PROGRAM:
// lexer.l
%{
#include <stdio.h>
#include <string.h>
%}
%option noyywrap
ID [a-zA-Z][a-zA-Z0-9]*
PLUS \+
MULTIPLY \*
LPAREN \(
RPAREN \)
WS [ \t\n]+
%%
{ID} { printf("ID: %s\n", yytext); }
{PLUS} { printf("PLUS\n"); }
{MULTIPLY} { printf("MULTIPLY\n"); }
{LPAREN} { printf("LPAREN\n"); }
{RPAREN} { printf("RPAREN\n"); }
{WS} { /* Ignore whitespace */ }
. { printf("Error: Invalid character\n"); }
%%
int main() {
yylex();
return 0;
6
INPUT & OUTPUT:
6
EXPERIMENT-7
OBJECTIVE:
Write a C program for implementing the functionalities of predictive parser for the mini language specified
inNote 1.
PROGRAM:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <ctype.h>
// Define token types
#define ID 1
#define PLUS 2
#define MULTIPLY 3
#define LPAREN 4
#define RPAREN 5
#define END 6
// Define grammar production
rules char *productions[] = {
"E->TE'",
"E'->+TE' | ε",
"T->FT'",
"T'->*FT' | ε",
"F->(E) | id"
};
// Function to get the next token from input
string int getNextToken(char **input) {
// Skip whitespaces
while (**input && isspace(**input))
(*input)++;
// Check for end of
input if (**input == '\0')
return END;
// Check for other
tokens switch (**input)
{
case '+':
(*input)++;
return PLUS;
case '*':
(*input)++;
return MULTIPLY;
case '(':
(*input)++;
return LPAREN;
case ')':
(*input)++;
return RPAREN;
default:
if (isalpha(**input)) {
(*input)++;
return ID;
} else {
printf("Invalid token: %c\n", **input);
6
exit(1);
}
}
}
// Function to match token
void match(int expected_token, char **input) {
int token = getNextToken(input);
if (token != expected_token) {
printf("Error: Expected token %d, got %d\n", expected_token, token);
exit(1);
}
}
// Function to parse E
void E(char **input);
// Function to parse E'
void E_prime(char **input);
// Function to parse T
void T(char **input);
// Function to parse T'
void T_prime(char **input);
// Function to parse F
void F(char **input);
// Function to parse E
void E(char **input)
{
printf("E -> TE'\n");
T(input);
E_prime(input);
}
// Function to parse E'
void E_prime(char **input) {
int token =
getNextToken(input); if (token
== PLUS) {
printf("E' -> +TE'\
n"); match(PLUS,
input); T(input);
E_prime(input);
} else {
printf("E' -> ε\n");
// Do nothing, epsilon production
}
}
// Function to parse T
void T(char **input)
{
printf("T -> FT'\n");
F(input);
T_prime(input);
}
// Function to parse T'
void T_prime(char **input) {
int token =
6
getNextToken(input); if (token
== MULTIPLY) {
printf("T' -> *FT'\n");
match(MULTIPLY, input);
6
F(input);
T_prime(input);
} else {
printf("T' -> ε\n");
// Do nothing, epsilon production
}
}
// Function to parse F
void F(char **input)
{
int token =
getNextToken(input); if (token
== LPAREN) {
printf("F -> (E)\n");
match(LPAREN, input);
E(input);
match(RPAREN, input);
} else if (token == ID)
{ printf("F -> id\n");
match(ID, input);
} else {
printf("Error: Invalid token\
n"); exit(1);
}
}
int main() {
char input[100];
printf("Enter the input string: ");
fgets(input, sizeof(input),
stdin);
input[strcspn(input, "\n")] = '\0'; // Remove trailing newline
char *input_ptr =
input; E(&input_ptr);
int token = getNextToken(&input_ptr);
if (token == END) {
printf("Input string is accepted!\n");
} else {
printf("Error: Unexpected token %d\n", token);
}
return 0;
}
6
INPUT & OUTPUT:
6
EXPERIMENT-8
OBJECTIVE:
*Write a C program for constructing of LL (1) parsing.
PROGRAM:
#include <stdio.h>
#include <stdlib.h>
#include
<string.h>
#include <ctype.h>
// Function prototypes
void error();
void push(char);
char pop();
void parse();
// Parsing table
char parsing_table[5][6][4] = {
{ "", "", "", "", "", "" },
{ "", "TE'", "", "TE'", "", "" },
{ "", "", "", "", "ε", "ε" },
{ "", "FT'", "", "FT'", "", "" },
{ "", "", "", "", "ε", "ε" }
};
// Stack
char stack[MAX_STACK_SIZE];
int top = -1;
// Input string
char input[MAX_INPUT_SIZE];
int input_index = 0;
// Push to stack
void push(char symbol) {
if (top >= MAX_STACK_SIZE - 1) {
printf("Stack Overflow\n");
exit(1);
}
stack[++top] = symbol;
}
6
}
return stack[top--];
}
// Error
function void
error() {
printf("Error: Invalid input\
n"); exit(1);
}
// Parse
void parse() {
push('$'); // Bottom of stack
marker push('E'); // Start symbol
while (1) {
char top_symbol = stack[top];
char lookahead = input[input_index];
int main() {
printf("Enter the input string:
"); scanf("%s", input);
parse();
return 0;
}
6
INPUT & OUTPUT:
6
EXPERIMENT-8
OBJECTIVE:
Construction of recursive descent parsing for the
followinggrammar
E->TE' E'->+TE/@ "@ represents
nullcharacter" T->FT'
T`->*FT'/@F->(E)/ID
PROGRAM:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdbool.h>
#include <string.h>
// Function prototypes
bool E(char*);
bool E_prime(char*);
bool T(char*);
bool T_prime(char*);
bool F(char*);
// Function to parse
E bool E(char*
input) {
input = skipWhitespace(input);
6
return false;
}
if (*input == '+') {
input++;
if (T(input) && E_prime(input)) {
return true;
} else {
return false;
}
}
// Function to parse
T bool T(char*
input) {
input = skipWhitespace(input);
return false;
}
if (*input == '*') {
input++;
if (F(input) && T_prime(input)) {
return true;
} else {
return false;
}
}
// Function to parse F
6
bool F(char* input) {
input = skipWhitespace(input);
if (*input == '(') {
input++;
if (E(input) && *input == ')') {
input++;
return true;
}
} else if (isID(*input)) {
while (isID(*input)) {
input++;
}
return true;
}
return false;
}
int main() {
char input[100];
return 0;
}
6
INPUT & OUTPUT:
6
EXPERIMENT-9
OBJECTIVE:
Write a program to Design LALR Bottom up Parser
PROGRAM:
#include <stdio.h
#include <stdlib.h>
#include <string.h>
// Grammar
char *grammar[] = {
"S->E",
"E->E+T",
"E->T",
"T->T*F",
"T->F",
"F->(E)",
"F->id"
};
// Action table
char *action_table[][7] = {
{" ", "s5", " ", "s4", " ", " ", " "},
{" ", " ", "s6", " ", " ", "accept", " "},
{" ", "s5", " ", "s4", " ", " ", " "},
6
{" ", "r6", "r6", " ", "r6", "r6", "r6"},
{" ", "s5", " ", "s4", " ", " ", " "},
};
// Goto table
int goto_table[][4] = {
{1, 2, 3, 0},
{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0},
{1, 2, 3, 0},
{0, 0, 0, 0},
{0, 0, 0, 0},
{1, 2, 3, 0},
{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0},
{1, 2, 3, 0},
{0, 0, 0, 0}
};
// Stack
int stack[MAX_STACK_SIZE];
int top = -1;
6
// Input string
char input[MAX_INPUT_SIZE];
int input_index = 0;
// Push to stack
void push(int state) {
printf("Stack Overflow\n");
exit(1);
}
stack[++top] = state;
}
if (top < 0) {
printf("Stack Underflow\n");
exit(1);
}
return stack[top--];
// Parse
void parse() {
while (1) {
int state = stack[top];
char lookahead = input[input_index];
'A'; push(goto_table[stack[top]][non_terminal]);
} else { // Error
int main() {
parse();
return 0;
6
INPUT & OUTPUT:
Input:
grammar:
6
EXPERIMENT-10
OBJECTIVE:
Program to implement semantic rules to calculate the expression that takes an expression with
digits+ and * and computes the value.
PROGRAM:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
while (*expression) {
if (isdigit(*expression)) {
num = num * 10 + (*expression - '0');
} else if (*expression == '+' || *expression == '*')
{ if (op == '+') {
result += num;
} else if (op == '*')
{ result *= num;
}
num = 0;
op = *expression;
}
expression++;
}
if (op == '+') {
result += num;
} else if (op == '*')
{ result *= num;
}
return result;
}
int main() {
char expression[100];
6
int result = evaluateExpression(expression);
printf("Result: %d\n", result);
return 0;
}
6
INPUT & OUTPUT:
Inp
Outp