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

Compiler Design labs

The document contains multiple C and Lex programs that perform various tasks such as checking if input is a digit, counting operators in expressions, validating comments, identifiers, and keywords, and generating three-address code. Each program includes a main function that prompts for user input and processes it according to the specified logic. Additionally, it provides information on Lex and Flex, tools for generating lexical analyzers, including installation and execution instructions.

Uploaded by

prajwolpuda100
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views

Compiler Design labs

The document contains multiple C and Lex programs that perform various tasks such as checking if input is a digit, counting operators in expressions, validating comments, identifiers, and keywords, and generating three-address code. Each program includes a main function that prompts for user input and processes it according to the specified logic. Additionally, it provides information on Lex and Flex, tools for generating lexical analyzers, including installation and execution instructions.

Uploaded by

prajwolpuda100
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 25

1. check_digit_or_string.c : https://www.online-cpp.

com/tW1vSGRVPd
#include <ctype.h>
#include <stdio.h>
#include <stdbool.h>
#include <string.h>

bool isDigit(const char *input) {


for (int i = 0; i < strlen(input); i++) {
if(!isdigit(input[i])) {
return false;
}
}
return true;
}

int main() {
char input[100];
printf("Enter number: ");
scanf("%s", input);

if(isDigit(input)) {
printf("Input is a digit\n");
} else {
printf("Input is a string\n");
}
}
2. count_operator.c : https://www.online-cpp.com/tUNIf473Rx
#include <stdio.h>

int count_operators(char *expression) {


int count = 0;
for (int i = 0; expression[i] != '\0'; i++) {
if (expression[i] == '+' || expression[i] == '-' || expression[i] == '*' ||
expression[i] == '/' || expression[i] == '=') {
count++;
}
}
return count;
}

int main() {
char expression[100];
printf("Enter an expression: ");
fgets(expression, 100, stdin);

int count = count_operators(expression);


printf("The number of operators in the expression is %d\n", count);

return 0;
}
3. valid_comment.c : https://www.online-cpp.com/o81IryF4kG
#include <stdio.h>
#include <stdbool.h>
#include <string.h>

bool isValidComment(const char *str) {


int length = strlen(str);

if (length < 2) {
return false; // Comment must be at least 2 characters (// or /*)
}

if (str[0] == '/' && str[1] == '/') {


return true; // Line comment
}

if (length < 4 || str[0] != '/' || str[1] != '*') {


return false; // Comment must start with /*
}

if (str[length - 2] != '*' || str[length - 1] != '/') {


return false; // Comment must end with */
}

return true;
}

int main() {
char inputString[100]; // Adjust the array size as needed

printf("Enter a string: ");


fgets(inputString, sizeof(inputString), stdin);
inputString[strcspn(inputString, "\n")] = '\0'; // Remove newline if present

if (isValidComment(inputString)) {
printf("'%s' is a valid C comment.\n", inputString);
} else {
printf("'%s' is not a valid C comment.\n", inputString);
}

return 0;
}
4. dfa_accept_ aba_as_substring.c :
https://www.online-cpp.com/B2zTwxWlRy
#include <cstring>
#include <iostream>
using namespace std;

// Function to check whether the given string is accepted by DFA or not


void checkValidDFA(string s)
{
// Stores initial state of DFA
int initial_state = 0;
// Stores previous state of DFA
int previous_state = initial_state;
// Stores final state of DFA
int final_state;
// Iterate through the string
for (int i = 0; i < s.length(); i++) {
// Checking for all combinations
if ((previous_state == 0 && s[i] == 'a') ||
(previous_state == 1 && s[i] == 'a')) {
final_state = 1;
}
if ((previous_state == 0 && s[i] == 'b') ||
(previous_state == 2 && s[i] == 'b')) {
final_state = 0;
}
if (previous_state == 1 && s[i] == 'b') {
final_state = 2;
}
if ((previous_state == 2 && s[i] == 'a') ||
(previous_state == 3)) {
final_state = 3;
}
// Update the previous_state
previous_state = final_state;
}
// If final state is reached
if (final_state == 3) {
cout << s+" => Accepted" << endl;
}
// Otherwise
else {
cout << s+" => Rejected" << endl;
}
}
int main()
{
// Check for "ababa"
checkValidDFA("ababa");
// Check for "bbaa"
checkValidDFA("bbaa");
return 0;
}
5. valid_identifier.c : https://www.online-cpp.com/t213QmKiyb
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <ctype.h>

bool isValidIdentifierChar(char c) {
return (isalnum(c) || c == '_');
}

bool isValidIdentifier(const char *str) {


if (strlen(str) == 0 || isdigit(str[0])) {
return false;
}

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


if (!isValidIdentifierChar(str[i])) {
return false;
}
}

return true;
}

int main() {
char inputString[100];

printf("Enter a string: ");


scanf("%s", inputString);

if (isValidIdentifier(inputString)) {
printf("'%s' is a valid identifier.\n", inputString);
} else {
printf("'%s' is not a valid identifier.\n", inputString);
}

return 0;
}
6. valid_keyword.c : https://www.online-cpp.com/eMIHfpbPla
#include <stdio.h>
#include <stdbool.h>
#include <string.h>

// Array of C keywords
const char *keywords[] = {
"break", "case", "char", "const", "continue", "default", "do",
"double", "else", "enum", "extern", "float", "for", "goto", "if",
"int", "long", "return", "sizeof", "struct", "switch", "typedef", "void", "while"
};

bool isKeyword(const char *str) {


int numKeywords = sizeof(keywords) / sizeof(keywords[0]);

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


if (strcmp(str, keywords[i]) == 0) {
return true;
}
}

return false;
}

int main() {
char inputString[50];

printf("Enter a string: ");


scanf("%s", inputString);

if (isKeyword(inputString)) {
printf("'%s' is a C keyword.\n", inputString);
} else {
printf("'%s' is not a C keyword.\n", inputString);
}

return 0;
}
7. recognize_token.c : https://www.online-cpp.com/dAPrgpM1qQ
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <ctype.h>

const char *keywords[] = {


"int", "float", "char", "if", "else", "while", "for", "return"
};

int numKeywords = sizeof(keywords) / sizeof(keywords[0]);

bool isInteger(const char *input) {


for (int i = 0; i < strlen(input); i++) {
if(!isdigit(input[i])) {
return false;
}
}
return true;
}

bool isIdentifier(const char *str) {


if (!isalpha(str[0]) && str[0] != '_') {
return false;
}
for (int i = 1; str[i] != '\0'; i++) {
if (!isalnum(str[i]) && str[i] != '_') {
return false;
}
}
return true;
}

bool isKeyword(const char *str) {


for (int i = 0; i < numKeywords; i++) {
if (strcmp(str, keywords[i]) == 0) {
return true;
}
}
return false;
}

int main() {
char input[100];
const char delimiters[] = " \t\n";
printf("Enter input: ");
fgets(input, sizeof(input), stdin);

char *token = strtok(input, delimiters);

while (token != NULL) {


if (isInteger(token)) {
printf("Integer: %s\n", token);
} else if (isIdentifier(token)) {
if (isKeyword(token)) {
printf("Keyword: %s\n", token);
} else {
printf("Identifier: %s\n", token);
}
} else {
printf("Operator or unknown: %s\n", token);
}
token = strtok(NULL, delimiters);
}

return 0;
}
Lex
Lex is a computer program that generates lexical analyzers. Lex reads an
input stream specifying the lexical analyzer and outputs source code
implementing the lexer in the C programming language.
Flex
FLEX (fast lexical analyzer generator) is a tool/computer program for
generating lexical analyzers (scanners or lexers) written by Vern Paxson in C
around 1987. It is used together with Berkeley Yacc parser generator or GNU
Bison parser generator. Flex and Bison both are more flexible than Lex and
Yacc and produces faster code. Bison produces parser from the input file
provided by the user. The function yylex() is automatically generated by the
flex when it is provided with a .l file and this yylex() function is expected by
parser to call to retrieve tokens from current/this token stream.
Note: The function yylex() is the main flex function that runs the Rule Section
and extension (.l) is the extension used to save the programs.
Installing flex
 On ubuntu
sudo apt-get update
sudo apt-get install flex
 On linux
sudo xbps-install flex
 On windows
https://www.geeksforgeeks.org/how-to-install-flex-on-windows/

Executing flex program


 Save the file with the extension .l or .lex
 To generate the C source file from the Flex program, run the following
command:
flex file_name.l
 This will generate a file named lex.yy.c in the same directory. Next,
compile the C source file using the following command:
gcc lex.yy.c -o output_file_name -lfl
 This command will produce an executable called output_file_name in
the current directory. Finally, you can run the program by executing the
following command:
./output_file_name
 Provide the input to program in case it is required
Example:
The Lexical- Analyzer Generator Lex , Structure of Lex Programs

Find out the Uppercase and lowercase of a string .


A tool called Lex (or in a more recent implementation Flex) allows to specify a lexical
analyzer by specifying regular expressions to describe patterns for tokens.
The input language is referred as Lex Language and the tool itself is the Lex
Complier.

How its work: The Lex complier transforms the input patterns into a transition
diagram and generates code in a file called lex.yy.c, that simulates this transition
diagram.

Use of Lex:

Lex source pgm(Lex.l) --> LEX COMPLIER --> lex.yy.c

lex.yy.c --> C COMPLIER --> a.out

Input stream --> a.out --> Sequence


of tokens

==>An input file lex.l is written in the Lex language and describe the lexical analyzer.
The Lex complier transforms lex.l to C program , in a file that is always named
lex.yy.c.
==>The C output is a.out that can take a stream of input characters and produce a
stream of tokens.
To understand the complete concept , just go through this below example.
Here is the source code of How to find out the lowercase and uppercase of a string??

%{

#include

int Upper=0;

int Lower=0;

%}

%%

[A-Z] {printf("Uppercase\t");Upper++;}

[a-z] {printf("Lowercase\t");Lower++;}

%%

int
yywrap()

return 1;

main()
{

printf("Enter a string\n");

yylex();

printf("Uppercase=%d and Lowercase=%d",Upper,Lower);


}
8. analyze_arithmetic_expression.l
/* program to analyze arithmetic expression */
%{
#include <stdio.h>
#include <string.h>
%}

%%
"int"|"float"|"char"|"void" { printf("Keyword: %s\n", yytext); }
[a-zA-Z][a-zA-Z0-9]* { printf("Identifier: %s\n", yytext); }
[0-9]+ { printf("Numeric Literal: %s\n", yytext); }
"=" { printf("Assignment Operator\n"); }
";" { printf("Semicolon\n"); }
[ \t] { /* Ignore space and tab characters */ }
\n { /* Ignore newline characters */ }
. { printf("Invalid input\n"); }
%%

int main() {
printf("Enter an input string:\n");
yylex();
return 0;
}

/*
EXAMPLE:
Enter an input string:
int a = 69;
Keyword: int
Identifier: a
Assignment Operator
Numeric Literal: 69
Semicolon
*/
9. check_digit.l
/* Lex program to check whether input is digit or not. */
%{
#include<stdio.h>
#include<stdlib.h>
%}
/* Rule Section */
%%
^[0-9]* printf("DIGIT");
^[^0-9]|[0-9]*[a-zA-Z] printf("NOT A DIGIT");
.;
%%
int main()
{
yylex();
return 0;
}

/*
EXAMPLE:
dfa
NOT A DIGIT
69
DIGIT
^C
*/
10. check_digit_repeatedly.l
/* Lex program to check whether input is digit or not. */
%{
#include<stdio.h>
#include<stdlib.h>
%}

/* Rule Section */
%%
^[0-9]* { printf("DIGIT\n"); }
^[^0-9]|[0-9]*[a-zA-Z] { printf("NOT A DIGIT\n"); }
. { /* Ignore other characters */ }
%%

int main()
{
char input[100];
int choice;

do {
printf("Enter a string:\n");
fgets(input, sizeof(input), stdin);
yy_scan_string(input);
yylex();

printf("Do you want to continue? (1: Yes, 0: No): ");


scanf("%d", &choice);
getchar();

} while (choice != 0);

return 0;
}

/*
EXAMPLE:
Enter a string:
69
DIGIT

Do you want to continue? (1: Yes, 0: No): 1


Enter a string:
asf
NOT A DIGIT

Do you want to continue? (1: Yes, 0: No): 1


Enter a string:
69s
NOT A DIGIT

Do you want to continue? (1: Yes, 0: No): 0


*/
11. check_keyword.l
/* Check whether given input string is keyword or not */
%{
#include <stdio.h>
#include <string.h>
%}

%%
"int"|"float"|"char"|"void"|"if"|"else"|"while" { printf("%s is a keyword\n",
yytext); }
. { printf("Not a keyword\n"); }
%%

int main() {
printf("Enter an input string:");
yylex();
return 0;
}

/*
EXAMPLE:
Enter an input string:int
int is a keyword
*/
12. count_operator.l
/* count the number of operator used in given input */
%{
#include <stdio.h>
#include <string.h>
int operatorCount = 0;
%}

%%
[+\-*/=] { operatorCount++; }
. { /* Ignore other characters */ }
%%

int main() {
char input[100];
printf("Enter an input string:\n");
fgets(input, sizeof(input), stdin);
yy_scan_string(input);
yylex();

printf("Number of operators: %d\n", operatorCount);

return 0;
}

/*
EXAMPLE:
Enter an input string:
int a = 5 + 6 * 9 - 5;

Number of operators: 4
*/
13. three_address_code.l
/* Write a flex program to generate three address code */
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
%}

%%
[0-9]+ { printf("t%d = %s\n", yylineno, yytext); }
[-+*/] { printf("t%d = t%d %s t%d\n", yylineno, yylineno-2, yytext,
yylineno-1); }
\n { /* Ignore newline character */ }
. { printf("Invalid input\n"); exit(1); }
%%

int main() {
printf("Enter an arithmetic expression:\n");
yylex();
return 0;
}

/*
EXAMPLE
Enter an arithmetic expression:
3*4*5
t1 = 3
t1 = t-1 * t0
t1 = 4
t1 = t-1 * t0
t1 = 5
^C
*/
14. intermediate_code_generation.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int i = 0, j = 0, no = 0, tmpch = 90;


char str[100], left[15], right[15];

struct exp {
int pos;
char op;
} k[15];

void findopr();
void explore();
void fleft(int);
void fright(int);

int main() {
printf("INTERMEDIATE CODE GENERATION\n");
printf("Enter the Expression: ");
scanf("%s", str);
printf("The intermediate code:\t\tExpression\n");
findopr();
explore();
return 0;
}

void findopr() {
for (i = 0; str[i] != '\0'; i++) {
if (str[i] == ':') {
k[j].pos = i;
k[j++].op = ':';
}
}

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


if (str[i] == '/') {
k[j].pos = i;
k[j++].op = '/';
}
}

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


if (str[i] == '*') {
k[j].pos = i;
k[j++].op = '*';
}
}

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


if (str[i] == '+') {
k[j].pos = i;
k[j++].op = '+';
}
}

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


if (str[i] == '-') {
k[j].pos = i;
k[j++].op = '-';
}
}
}

void explore() {
i = 0;
while (k[i].op != '\0') {
fleft(k[i].pos);
fright(k[i].pos);
str[k[i].pos] = tmpch--;
printf("\t%c := %s%c%s\t\t", str[k[i].pos], left, k[i].op, right);
for (j = 0; j < strlen(str); j++) {
if (str[j] != '$')
printf("%c", str[j]);
}
printf("\n");
i++;
}
fright(-1);

if (no == 0) {
fleft(strlen(str));
printf("\t%s := %s\n", right, left);
exit(0);
}

printf("\t%s := %c\n", right, str[k[--i].pos]);


}

void fleft(int x) {
int w = 0, flag = 0;
x--;

while (x >= 0 && str[x] != '+' && str[x] != '*' && str[x] != '=' && str[x] !=
'\0' && str[x] != '-' && str[x] != '/' && str[x] != ':') {
if (str[x] != '$' && flag == 0) {
left[w++] = str[x];
left[w] = '\0';
str[x] = '$';
flag = 1;
}
x--;
}
}

void fright(int x) {
int w = 0, flag = 0;
x++;

while (x < strlen(str) && str[x] != '+' && str[x] != '*' && str[x] != '\0' &&
str[x] != '=' && str[x] != ':' && str[x] != '-' && str[x] != '/') {
if (str[x] != '$' && flag == 0) {
right[w++] = str[x];
right[w] = '\0';
str[x] = '$';
flag = 1;
}
x++;
}
}

You might also like