You are on page 1of 33

CD Lab Manual Kalp Adhwaryu - 19124065

LAB Manual

Compiler Design Laboratory (CS402)

Navrachana University
School of Engineering and Technology
Department
of
Computer Science and Engineering
Semester – VI

Enrolment ID: 19124065


Student Name: Kalp Adhwaryu
Course In-charge: Prof. Vaibhavi Patel

Academic Year: 2021-2022


CD Lab Manual Kalp Adhwaryu - 19124065

TABLE OF CONTENT

Sr. Experiment Title Date of


No Performance
a) Program to count digits, vowels, consonant and symbols in C. 20-01-2022
1 b) Program to check validation of User Name and Password* in C. 20-01-2022
c) Write a program to identify whether a given line is a comment or not. 27-01-2022
03-02-2022
a) Write a C program to recognize strings end with ‘ab’
03-02-2022
b) Write a C program to simulate lexical analyzer for validating operators
2 10-02-2022
c) Design a lexical analyzer to identify from given pattern is keyword or identifier.
d) Program to implement Lexical Analyzer.
10-02-2022
3 To Study about Lexical Analyzer Generator(LEX) and Flex(Fast Lexical Analyzer) 17-02-2022
Implement following programs using Lex.
a. Create a Lexer to take input from text file and count no of characters, no. of lines & 17-02-2022
no. of words.
b. Write a Lex program to count number of vowels and consonants in a given input 24-02-2022
4 string.
c. Write a Lex program to print out all numbers from the given file. 03-03-2022
d. Write a Lex program which adds line numbers to the given file and display the same
onto the standard output. 24-03-2022
e. Write a Lex program to printout all HTML tags in file. 31-03-2022
a. Write a Lex program to count the number of comment lines in a given C program.
14-04-2022
Also eliminate them and copy that program into separate file.
5
b. Write a Lex program to print keywords, identifiers, operators, numbers in a given C
21-04-2022
program.
6 Program to implement Predictive Parsing LL(1) in C. -

7 Program to implement Recursive Descent Parsing in C. 21-04-2022


a. To Study about Yet Another Compiler-Compiler(YACC).
b. Create Yacc and Lex specification files to recognizes arithmetic expressions involving
8 +, -, * and / . 28-04-2022
c. Create Yacc and Lex specification files are used to generate a calculator which
accepts integer and float type arguments.
CD Lab Manual Kalp Adhwaryu - 19124065

Practical 1

Aim 1: Program to count digits, vowels, consonant and symbols in C.

Code:

#include <stdio.h>

void main()
{
    char str[100];
    int i, vow_count = 0, conso_count = 0, digi_count = 0, spaces = 0,
sym_count = 0;

    printf("\nEnter a string :");


    scanf("%s", str);
    for (i = 0; str[i] != '\0'; i++)
    {
        if (str[i] == 'a' || str[i] == 'e' || str[i] == 'i' || str[i] == 'o'
|| str[i] == 'u' || str[i] == 'A' || str[i] == 'E' || str[i] == 'I' || str[i]
== 'O' || str[i] == 'U')
        {
            vow_count++;
        }
        else if ((str[i] >= 'a' && str[i] <= 'z') || (str[i] >= 'A' && str[i]
<= 'Z'))
        {
            conso_count++;
        }
        else if (str[i] >= '0' && str[i] <= '9')
        {
            digi_count++;
        }
        else if (str[i] == ' ')
        {
            spaces++;
        }
        else
        {
            sym_count++;
        }
    }

    printf("\nVowels = %d", vow_count);


    printf("\nConsonants = %d", conso_count);
    printf("\nDigits = %d", digi_count);
    printf("\nWhite spaces = %d", spaces);
    printf("\nSymbols = %d", sym_count);
CD Lab Manual Kalp Adhwaryu - 19124065

Output:

Aim 2: Program to check validation of User Name and Password* in C.

Code:

#include <stdio.h>
#include <string.h>
#include <stdbool.h>
void main()
{
    char pass[20], ch;
    int i, number, special, capital, small, length;

    number = special = capital = small = 0;


    printf("\nRules for password\n1. Password should contain atleast one
uppercase,one lowercase letter and one numeric value\n2. Password should have
atleast one special charecter(!,%,&,@,#,$,^,*,?,_,~)\n3. Password length
should be atleast between 8 and 16\nEnter the password :");
    gets(pass);
    for (i = 0; pass[i] != '\0'; i++)
    {
        if (pass[i] >= '0' && pass[i] <= '9')
            number = 1;
        else if (pass[i] >= 'a' && pass[i] <= 'z')
            small = 1;
        else if (pass[i] >= 'A' && pass[i] <= 'Z')
            capital = 1;
        else if (pass[i] == '!' || pass[i] == '@' || pass[i] == '#' || pass[i]
== '$' || pass[i] == '%' || pass[i] == '*' || pass[i] == '&' || pass[i] == '#'
|| pass[i] == '^' || pass[i] == '_' || pass[i] == '?' || pass[i] == '~')
            special = 1;
    }
    if (strlen(pass) >= 8 || strlen(pass) <= 16)
    {
CD Lab Manual Kalp Adhwaryu - 19124065

        length = 1;
    }
    if (number == 0 || special == 0 || capital == 0 || small == 0 || length ==
0)
    {

        printf("\nThe entered password is invalid");


    }
    else
    {
        printf("\nThe entered password is valid");
    }
}

Output:

Aim 3: Write a program to identify whether a given line is a comment or not.

Code:

#include <stdio.h>
void main()
{
    char str[100];
    int i = 2, flag = 0;

    printf("\n Enter comment:");


    gets(str);
    if (str[0] == '/')
    {
        if (str[1] == '/')
            printf("\nSingle line comment");
        else if (str[1] == '*')
        {
            for (i = 2; i <= 30; i++)
CD Lab Manual Kalp Adhwaryu - 19124065

            {
                if (str[i] == '*' && str[i + 1] == '/')
                {
                    printf("\n Multiline comment");
                    flag = 1;
                    break;
                }
                else
                    continue;
            }
            if (flag == 0)
                printf("\n It is not a comment");
        }
        else
            printf("\n It is not a comment");
    }
    else
        printf("\n It is not a comment");
}

Output:
CD Lab Manual Kalp Adhwaryu - 19124065

Practical 2

Aim 1: Write a C program to recognize strings end with ‘ab’

Code:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void main()
{
    char str[100], c;
    int state = 0, i = 0;
    printf("Enter a string :");
    gets(str);
    while (str[i] != '\0')
    {
        switch (state)
        {
        case 0:
            c = str[i++];
            if (c == 'a')
                state = 1;
            else if (c == 'b')
                state = 0;
            else
                state = 3;
            break;

        case 1:
            c = str[i++];
            if (c == 'a')
                state = 1;
            else if (c == 'b')
                state = 2;
            else
                state = 3;
            break;

        case 2:
            c = str[i++];
            if (c == 'a')
                state = 1;
            else if (c == 'b')
                state = 0;
            else
                state = 3;
            i++;
CD Lab Manual Kalp Adhwaryu - 19124065

            break;

        case 3:
            printf("String not acceptable");
            exit(0);
        default:
            break;
        }
    }
    if (state == 2)
        printf("String accepted and ends with ab");
    else
        printf("String accepted but doesn't end with ab");
}

Output:

Aim 2: Write a C program to simulate lexical analyzer for validating operators

Code:

#include <stdio.h>
#include <conio.h>
void main()
{
    char s[5];
    printf("\n Enter any operator:");
    gets(s);
    switch (s[0])
    {
    case '>':
        if (s[1] == '=')
            printf("\n Greater than or equal");
        else
            printf("\n Greater than");
        break;
    case '<':
CD Lab Manual Kalp Adhwaryu - 19124065

        if (s[1] == '=')
            printf("\n Less than or equal");
        else
            printf("\nLess than");
        break;
    case '=':
        if (s[1] == '=')
            printf("\nEqual to");
        else
            printf("\nAssignment");
        break;
    case '!':
        if (s[1] == '=')
            printf("\nNot Equal");
        else
            printf("\n Bit Not");
        break;
    case '&':
        if (s[1] == '&')
            printf("\nLogical AND");
        else
            printf("\n Bitwise AND");
        break;
    case '|':
        if (s[1] == '|')
            printf("\nLogical OR");
        else
            printf("\nBitwise OR");
        break;
    case '+':
        printf("\n Addition");
        break;
    case '-':
        printf("\nSubstraction");
        break;
    case '*':
        printf("\nMultiplication");
        break;
    case '/':
        printf("\nDivision");
        break;
    case '%':
        printf("Modulus");
        break;
    default:
        printf("\n Not a operator");
    }
}
CD Lab Manual Kalp Adhwaryu - 19124065

Output:

Aim 3: Design a lexical analyzer to identify from given pattern is keyword or identifier.

Code:

#include <stdio.h>
#include <conio.h>
#include <ctype.h>
void main()
{
    char str[10];
    int flag, i = 1;
    printf("\n Enter a string:");
    gets(str);
    if (isalpha(str[0]))
        flag = 1;
    else
        printf("\n Not a valid identifier");
    while (str[i] != '\0')
    {
        if (!isdigit(str[i]) && !isalpha(str[i]))
        {
            flag = 0;
            break;
        }
        else if (strcmp("for", str) == 0 || strcmp("while", str) == 0 ||
strcmp("do", str) == 0 || strcmp("int", str) == 0 || strcmp("float", str) == 0
|| strcmp("char", str) == 0 || strcmp("double", str) == 0 || strcmp("static",
str) == 0 || strcmp("switch", str) == 0 || strcmp("case", str) == 0)
            flag = 3;
        i++;
CD Lab Manual Kalp Adhwaryu - 19124065

    }
    if (flag == 1)
        printf("\n Valid identifier");
    else if (flag == 3)
        printf("\nIt's a keyword");
}

Output:

Aim 4: Program to implement Lexical Analyzer.

Code:

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

bool isDelimiter(char ch)


{
    if (ch == ' ' || ch == '+' || ch == '-' || ch == '*' ||
        ch == '/' || ch == ',' || ch == ';' || ch == '>' ||
        ch == '<' || ch == '=' || ch == '(' || ch == ')' ||
        ch == '[' || ch == ']' || ch == '{' || ch == '}')
        return (true);
    return (false);
}

bool isOperator(char ch)


CD Lab Manual Kalp Adhwaryu - 19124065

{
    if (ch == '+' || ch == '-' || ch == '*' ||
        ch == '/' || ch == '>' || ch == '<' ||
        ch == '=')
        return (true);
    return (false);
}

bool validIdentifier(char *str)


{
    if (str[0] == '0' || str[0] == '1' || str[0] == '2' ||
        str[0] == '3' || str[0] == '4' || str[0] == '5' ||
        str[0] == '6' || str[0] == '7' || str[0] == '8' ||
        str[0] == '9' || isDelimiter(str[0]) == true)
        return (false);
    return (true);
}

bool isKeyword(char *str)


{
    if (!strcmp(str, "if") || !strcmp(str, "else") ||
        !strcmp(str, "while") || !strcmp(str, "do") ||
        !strcmp(str, "break") ||
        !strcmp(str, "continue") || !strcmp(str, "int") || !strcmp(str,
"double") || !strcmp(str, "float") || !strcmp(str, "return") || !strcmp(str,
"char") || !strcmp(str, "case") || !strcmp(str, "char") || !strcmp(str,
"sizeof") || !strcmp(str, "long") || !strcmp(str, "short") || !strcmp(str,
"typedef") || !strcmp(str, "switch") || !strcmp(str, "unsigned") || !
strcmp(str, "void") || !strcmp(str, "static") || !strcmp(str, "struct") || !
strcmp(str, "goto"))
        return (true);
    return (false);
}

bool isInteger(char *str)


{
    int i, len = strlen(str);

    if (len == 0)
        return (false);
    for (i = 0; i < len; i++)
    {
        if (str[i] != '0' && str[i] != '1' && str[i] != '2' && str[i] != '3'
&& str[i] != '4' && str[i] != '5' && str[i] != '6' && str[i] != '7' && str[i]
!= '8' && str[i] != '9' || (str[i] == '-' && i > 0))
            return (false);
    }
    return (true);
CD Lab Manual Kalp Adhwaryu - 19124065

bool isRealNumber(char *str)


{
    int i, len = strlen(str);
    bool hasDecimal = false;

    if (len == 0)
        return (false);
    for (i = 0; i < len; i++)
    {
        if (str[i] != '0' && str[i] != '1' && str[i] != '2' && str[i] != '3'
&& str[i] != '4' && str[i] != '5' && str[i] != '6' && str[i] != '7' && str[i]
!= '8' && str[i] != '9' && str[i] != '.' ||
            (str[i] == '-' && i > 0))
            return (false);
        if (str[i] == '.')
            hasDecimal = true;
    }
    return (hasDecimal);
}

char *subString(char *str, int left, int right)


{
    int i;
    char *subStr = (char *)malloc(
        sizeof(char) * (right - left + 2));

    for (i = left; i <= right; i++)


        subStr[i - left] = str[i];
    subStr[right - left + 1] = '\0';
    return (subStr);
}

void parse(char *str)


{
    int left = 0, right = 0;
    int len = strlen(str);

    while (right <= len && left <= right)


    {
        if (isDelimiter(str[right]) == false)
            right++;

        if (isDelimiter(str[right]) == true && left == right)


        {
            if (isOperator(str[right]) == true)
                printf("'%c' IS AN OPERATOR\n", str[right]);
CD Lab Manual Kalp Adhwaryu - 19124065

            right++;
            left = right;
        }
        else if (isDelimiter(str[right]) == true && left != right || (right ==
len && left != right))
        {
            char *subStr = subString(str, left, right - 1);

            if (isKeyword(subStr) == true)
                printf("'%s' IS A KEYWORD\n", subStr);

            else if (isInteger(subStr) == true)


                printf("'%s' IS AN INTEGER\n", subStr);

            else if (isRealNumber(subStr) == true)


                printf("'%s' IS A REAL NUMBER\n", subStr);

            else if (validIdentifier(subStr) == true && isDelimiter(str[right


- 1]) == false)
                printf("'%s' IS A VALID IDENTIFIER\n", subStr);

            else if (validIdentifier(subStr) == false && isDelimiter(str[right


- 1]) == false)
                printf("'%s' IS NOT A VALID IDENTIFIER\n", subStr);
            left = right;
        }
    }
    return;
}

int main()
{

    char str[100] = "float a,b=3,c=5;a=b+c;printf(a)";


    parse(str);
    return (0);
}
CD Lab Manual Kalp Adhwaryu - 19124065

Output:
CD Lab Manual Kalp Adhwaryu - 19124065

Practical 3

Aim: To Study about Lexical Analyzer Generator(LEX) and Flex(Fast Lexical Analyzer)

Code:

Sample.l:

%{

#include<stdio.h>

int s_letters=0, c_letters=0, num=0;

%}

%%

[a-z] s_letters++;
[A-Z] c_letters++;
[0-9] num++;

%%

main(void)

yyin= fopen("myfile.txt","r");

yylex();
printf("\nThis File contains ...");
printf("\n%d small letters", s_letters);
printf("\n%d cap letters", c_letters);
printf("\n%d digits", num);

int yywrap()

return(1);

Myfile.txt:
CD Lab Manual Kalp Adhwaryu - 19124065

Output:

Practical 4
CD Lab Manual Kalp Adhwaryu - 19124065

Aim 1: Create a Lexer to take input from text file and count no of characters, no. of lines &
no. of words.

Code:

Sample.l file:

%{

#include<stdio.h>

int words=0, lines=0, chars=0;

%}

%%

[a-zA-Z] chars++;
\n { lines++; words++;}
[\t ' '] words++;

%%

main(void)

{
yyin= fopen("myfile.txt","r");
yylex();

printf(" This File contains ...");

printf("\n\t%d chars", chars);

printf("\n\t%d lines", lines+1);

printf("\n\t%d words", (words+1));


}

int yywrap()
{

return(1);

Myfile.txt:
CD Lab Manual Kalp Adhwaryu - 19124065

Output:

Aim 2: Write a Lex program to count number of vowels and consonants in a given input
string.

Code:

Sample.l:

%{
int vow_count=0;
int const_count =0;
%}

%%
[aeiouAEIOU] {vow_count++;}
[a-zA-Z] {const_count++;}
%%
int yywrap(){}
int main()
{
printf("Enter the string of vowels and consonents:");
yylex();
printf("Number of vowels are: %d\n", vow_count);
printf("Number of consonants are: %d\n", const_count);
return 0;
}

Output:

Aim 3: Write a Lex program to count number of vowels and consonants in a given input
string.
CD Lab Manual Kalp Adhwaryu - 19124065

Code:

Sample.l:

%{
#include <stdio.h>
%}
%%
[0-9]+ { printf("%s\n", yytext); }
.|\n ;
%%
int yywrap(){}
main()
{
yyin= fopen("myfile.txt","r");
printf("Numbers in the file are \n");
yylex();
}

Myfile.txt:

Output:

Aim 4: Write a Lex program which adds line numbers to the given file and display the same
onto the standard output.

Code:

Sample.l:

%{
int line_number = 1; // initializing line number to 1
%}

line .*\n
CD Lab Manual Kalp Adhwaryu - 19124065

%%
{line} { fprintf(yyout,"%10d %s", line_number++, yytext); }

%%

int yywrap(){}

int main(int argc, char*argv[])


{
extern FILE *yyin;

yyin = fopen("input.txt","r");

yyout = fopen("output.txt", "w");

yylex();

return 0;
}

Input.txt:

Output:

Aim 5: Write a Lex program to printout all HTML tags in file.


CD Lab Manual Kalp Adhwaryu - 19124065

Code:

Sample.l:

%{
#include <stdio.h>
%}
%%
"<"[^>]*> { printf("HTML Tag: %s\n", yytext); }
.|\n ;
%%
int yywrap(){}
main()
{
yyin= fopen("myfile.txt","r");
yylex();
}

Myfile.txt:

Output:

Practical 5
CD Lab Manual Kalp Adhwaryu - 19124065

Aim 1: Write a Lex program to count the number of comment lines in a given C program.
Also eliminate them and copy that program into separate file.

Code:

Sample.l file:

%{
#include<stdio.h>
int single=0;
int multi=0;
%}

%%
"//".*\n { ++single; fprintf(yyout,"%s", " ");}
"/*"[^*/]*"*/" { ++multi; fprintf(yyout,"%s", " ");}
. { fprintf(yyout,"%s", yytext);}
%%
int yywrap(){}
int main(int argc, int **argv)
{
extern FILE *yyin;
yyin=fopen("input.txt","r");
yyout =fopen("output.txt", "w");
yylex();
printf("\nNo of single line comment = %d ", single);
printf("\nNo of multi line comment = %d ", multi);
return 0;
}

Input.txt:

Output:
CD Lab Manual Kalp Adhwaryu - 19124065

Output.txt:

Aim 2: Write a Lex program to print keywords, identifiers, operators, numbers in a given C
program.

Code:

Sample.l file:

%{
#include<stdio.h>
%}

%%
auto|double|int|struct|break|else|long|switch|case|enum|register|typedef|char|
extern|return|union|continue|for|signed|void|do|if|static|while|default|goto|sizeof|
volatile|const|float|short|printf|scanf {ECHO; printf(" => KEYWORD\t");}

[+-/=*%] {ECHO; printf(" => OPERATOR\t");}

[a-z]([a-z]|[0-9])* {ECHO; printf(" => IDENTIFIER\t");}

[0-9]* {ECHO; printf(" => NUMBER\t");}

.|;

%%

int yywrap()
{
return 1;
}
CD Lab Manual Kalp Adhwaryu - 19124065

int main(void)
{

yylex();
return 0;
}

Input:

Output:

Practical 7
CD Lab Manual Kalp Adhwaryu - 19124065

Aim: Program to implement Recursive Descent Parsing in C.

Code:

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

char input[100];
int i, l;
int E();
int EP();
int T();
int TP();
int F();
int match(char t);

void main()
{
    printf("\nRecursive descent parsing for the following grammar\n");
    printf("\nE->TE'\nE'->+TE'/@\nT->FT'\nT'->*FT'/@\nF->(E)/ID\n");
    printf("\nEnter the string to be checked:");
    gets(input);

    if (E())
    {
        if (input[i + 1] == '\0')
            printf("\nString is accepted");
        else
            printf("\nString is not accepted");
    }
    else
        printf("\nString not accepted");
    getch();
}

int E()
{
    if (T())
    {
        if (EP())
            return (1);
        else
            return (0);
    }
    else
        return (0);
CD Lab Manual Kalp Adhwaryu - 19124065

int EP()
{
    if (input[i] == '+')
    {
        i++;
        if (T())
        {
            if (EP())
                return (1);
            else
                return (0);
        }
        else
            return (0);
    }
    else
        return (1);
}

int T()
{
    if (F())
    {
        if (TP())
            return (1);
        else
            return (0);
    }
    else
        return (0);
}

int TP()
{
    if (input[i] == '*')
    {
        i++;
        if (F())
        {
            if (TP())
                return (1);
            else
                return (0);
        }
        else
            return (0);
CD Lab Manual Kalp Adhwaryu - 19124065

    }
    else
        return (1);
}

int F()
{
    if (input[i] == '(')
    {
        i++;
        if (E())
        {
            if (input[i] == ')')
            {
                i++;
                return (1);
            }
            else
                return (0);
        }
        else
            return (0);
    }
    else if (input[i] >= 'a' && input[i] <= 'z' || input[i] >= 'A' && input[i]
<= 'Z')
    {
        i++;
        return (1);
    }
    else
        return (0);
}
int E2()
{
    if (l == '+')
    {
        match('+');
        match('i');
        E2();
    }
}

// Match function
int match(char t)
{
    if (l == t)
    {
        l = getchar();
CD Lab Manual Kalp Adhwaryu - 19124065

    }
    else
        printf("Error");
}

Output:

Practical 8
CD Lab Manual Kalp Adhwaryu - 19124065

Aim 1: To Study about Yet Another Compiler-Compiler (YACC).

 YACC stands for Yet Another Compiler Compiler.


 YACC provides a tool to produce a parser for a given grammar.
 YACC is a program designed to compile a LALR (1) grammar.
 It is used to produce the source code of the syntactic analyzer of the language produced
by LALR (1) grammar.
 The input of YACC is the rule or grammar and the output is a C program.

Input: A .y file

Output: A parser y.tab.c (yacc)

 The output file "file.output" contains the parsing tables.


 The file "file.tab.h" contains declarations.
 The parser called the yyparse ().
 Parser expects to use a function called yylex () to get tokens.

Aim 2: Create Yacc and Lex specification files to recognizes arithmetic expressions involving
+, -, * and /.

Code:

b.l file:

%{
#include <stdlib.h>
void yyerror(char *);
#include "b.tab.h"
%}
%%
[0-9]+ {
yylval = atoi(yytext);
return INTEGER;
}
[+-/*\n] return *yytext;
[ \t] ; /* skip whitespace */
. yyerror("invalid character");
%%
int yywrap() {
return 0;
}
CD Lab Manual Kalp Adhwaryu - 19124065

b.y file:

%{
#include <stdio.h>
int yylex(void);
void yyerror(char *);
%}
%token INTEGER
%%
S: S E '\n' { printf("valid \n"); }
|;
E:E '+' E ;
| E '-' E ;
| E '*' E ;
| E '/' E ;
| INTEGER ;
%%
void yyerror(char *s) {
fprintf(stderr, "%s\n", s);
}
int main() {
yyparse();
return 0;
}

Output:
CD Lab Manual Kalp Adhwaryu - 19124065

Aim 3: Create Yacc and Lex specification files are used to generate a calculator which
accepts integer and float type arguments.

Code:

b.l file:

%{
#include <stdlib.h>
void yyerror(char *);
#include "b.tab.h"
%}
%%
[0-9]+ {
yylval = atoi(yytext);
return INTEGER;
}
[+-/*\n] return *yytext;
[ \t] ; /* skip whitespace */
. yyerror("invalid character");
%%
int yywrap() {
return 0;
}

b.y file:

%{
#include <stdio.h>
int yylex(void);
void yyerror(char *);
%}
%token INTEGER
%%
S:
S E '\n' { printf("%d\n", $2); }
|;
E:E '+' E { $$ = $1 + $3; }
| E '-' E { $$ = $1 - $3; }
| E '*' E { $$ = $1 * $3; }
| E '/' E { $$ = $1 / $3; }
| INTEGER { $$ = $1; }
%%
void yyerror(char *s) {
fprintf(stderr, "%s\n", s);
}
CD Lab Manual Kalp Adhwaryu - 19124065

int main() {
yyparse();
return 0;
}

Output:

You might also like