1. Design a lexical analyser for given language and the lexical analyser 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.
#include <stdio.h>
#include <string.h>
#include <ctype.h>
void keyword(char str[10])
{
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)
printf(“n%s is a keyword”,str);
else
printf(“n%s is an identifier”,str);
}
int main()
{
FILE *f1,*f2,*f3;
char c,str[10];
int num[100],lineno=0,tokenvalue=0,i=0,j=0,k=0;
f1=fopen(“input.txt”,”w”);
while((c=getchar())!=EOF)
putc(c,f1);
fclose(f1);
f1=fopen(“input.txt”,”r”);
f2=fopen(“identifier.txt”,”w”);
f3=fopen(“special.txt”,”w”);
while((c=getc(f1))!=EOF)
{
if(isdigit(c))
{
tokenvalue=c-‘0’;
while(isdigit(c=getc(f1)))
tokenvalue=tokenvalue*10+(c-‘0’);
num[i++]=tokenvalue;
ungetc(c,f1);
}
else if(isalpha(c))
{
putc(c,f2);
while(isalnum(c=getc(f1))||c==’_’)
putc(c,f2);
putc(‘ ‘,f2);
ungetc(c,f1);
}
else if(c==’ ‘||c==’t’)
{
}
else if(c==’n’)
{
lineno++;
}
else
{
putc(c,f3);
}
}
fclose(f1);
fclose(f2);
fclose(f3);
printf(“nNumbers in program:”);
for(j=0;j<i;j++)
printf(” %d”,num[j]);
f2=fopen(“identifier.txt”,”r”);
printf(“nKeywords and Identifiers:”);
while((c=getc(f2))!=EOF)
{
if(c!=’ ‘)
str[k++]=c;
else
{
str[k]=”;
keyword(str);
k=0;
}
}
fclose(f2);
f3=fopen(“special.txt”,”r”);
printf(“nSpecial characters:”);
while((c=getc(f3))!=EOF)
printf(“%c “,c);
fclose(f3);
printf(“nTotal number of lines: %dn”,lineno);
}
2. a. Write a C program to identify whether a given line is a comment or not
#include <stdio.h>
int main()
{
char line[200];
int i,isMultiEnd=0;
fgets(line,sizeof(line),stdin);
if(line[0]!=’/’)
{
printf(“Not a commentn”);
return 0;
}
if(line[1]==’/’)
{
printf(“Single-line commentn”);
return 0;
}
if(line[1]==’*’)
{
for(i=2;line[i]!=”&&line[i+1]!=”;i++)
{
if(line[i]==’*’&&line[i+1]==’/’)
{
isMultiEnd=1;
break;
}
}
if(isMultiEnd)
printf(“Multi-line commentn”);
else
printf(“Not a commentn”);
}
else
printf(“Not a commentn”);
}
b.Write a C program to test whether a given identifier is valid or not.
#include <stdio.h>
#include <ctype.h>
#include <string.h>
int isKeyword(const char *s)
{
const char *keywords[]={“auto”,”break”,”case”,”char”,”const”,”continue”,”default”,”do”,”double”,”else”,”enum”,”extern”,”float”,”for”,”goto”,”if”,”int”,”long”,”register”,”return”,”short”,”signed”,”sizeof”,”static”,”struct”,”switch”,”typedef”,”union”,”unsigned”,”void”,”volatile”,”while”};
int i,n=sizeof(keywords)/sizeof(keywords[0]);
for(i=0;i<n;i++)
if(strcmp(s,keywords[i])==0)
return 1;
return 0;
}
int main()
{
char id[100];
int i;
scanf(“%s”,id);
if(!(isalpha(id[0])||id[0]==’_’))
{
printf(“Not a valid identifiern”);
return 0;
}
for(i=1;id[i]!=”;i++)
{
if(!(isalnum(id[i])||id[i]==’_’))
{
printf(“Not a valid identifiern”);
return 0;
}
}
if(isKeyword(id))
printf(“Not a valid identifier (keyword)n”);
else
printf(“Valid identifiern”);
}
3. Write a C program to simulate lexical analyzer for validating operators
#include <stdio.h>
#include <string.h>
int main()
{
char op[3];
scanf(“%s”,op);
char *operators[]={“+”,”-“,”*”,”/”,”%”,”==”,”!=”,”<“,”>”,”<=”,”>=”};
for(int i=0;i<11;i++)
{
if(strcmp(op,operators[i])==0)
{
printf(“Valid Operatorn”);
return 0;
}
}
printf(“Invalid Operatorn”);
}
4. To Study about Lexical Analyzer Generator (LEX) and Flex (Fast Lexical Analyzer)
%{
#include <stdio.h>
#include <stdlib.h>
int num, r, digit = 0, count = 0, pcount = 0, i;
char a[20];
%}
DIGIT [0-9]
%%
{DIGIT}+
{
num = atoi(yytext);
while (num != 0)
{
r = num % 16;
digit = ‘0’ + r;
if (digit > ‘9’)
digit += 7;
a[count++] = digit;
num = num / 16;
}
for (i = count – 1; i >= pcount; –i)
printf(“%c”, a[i]);
pcount = count;
}
n ;
. ;
%%
int main()
{
yylex();
return 0;
}
int yywrap()
{
return 1;
}
5. Implement following programs using Lex.
a. Create a Lexer to take input from text file and count no of characters, no. of lines & no. of
words.
%{
#include <stdio.h>
int words=0,chars=0,lines=0;
%}
%%
n { lines++; chars++; }
[ t] { chars++; }
[^ tn]+ { words++; chars+=yyleng; }
%%
int main()
{
yylex();
printf(“Lines:%d Words:%d Chars:%dn”,lines,words,chars);
}
int yywrap(){ return 1; }
b. Write a Lex program to count number of vowels and consonants in a given input string.
%{
#include <stdio.h>
int v=0,c=0;
%}
%%
[aeiouAEIOU] { v++; }
[a-zA-Z] { c++; }
%%
int main()
{
yylex();
printf(“Vowels:%d Consonants:%dn”,v,c);
}
int yywrap(){ return 1; }
6. Implement following programs using Lex.a. Write a Lex program to print out all numbers from the given file.
%{
#include <stdio.h>
extern FILE *yyin;
%}
%%
[0-9]+ { printf(“%sn”,yytext); }
.|n ;
%%
int main(int argc,char *argv[])
{
yyin=fopen(argv[1],”r”);
yylex();
}
int yywrap(){ return 1; }
b. Write a Lex program to printout all HTML tags in file.c.
%{
#include <stdio.h>
extern FILE *yyin;
%}
%%
“<“[^>]+”>” { printf(“%sn”,yytext); }
.|n ;
%%
int main(int argc,char *argv[])
{
yyin=fopen(argv[1],”r”);
yylex();
}
int yywrap(){ return 1; }
7. Write a Lex program which adds line numbers to the given file and display the same onto the
standard output.
%{
#include <stdio.h>
int line=1;
extern FILE *yyin;
%}
%%
n { line++; printf(“n%d:”,line); }
. { printf(“%s”,yytext); }
%%
int main()
{
yyin=fopen(“input.txt”,”r”);
printf(“%d:”,line);
yylex();
}
int yywrap(){ return 1; }
8. Write a C program for constructing of LL (1) parsing.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char s[50], stack[50];
int main()
{
char m[5][6][5] = {
{“tb”, “”, “”, “tb”, “”, “”},
{“”, “+tb”, “”, “”, “^”, “^”},
{“fc”, “”, “”, “fc”, “”, “”},
{“”, “”, “*fc”, “”, “^”, “^”},
{“i”, “”, “”, “(e)”, “”, “”}
};
int size[5][6] = {
{2,0,0,2,0,0},
{0,3,0,0,0,0},
{2,0,0,2,0,0},
{0,0,3,0,0,0},
{1,0,0,3,0,0}
};
int i, j, k, n, stx1, stx2;
scanf(“%s”, s);
strcat(s, “$”);
n = strlen(s);
stack[0] = ‘$’;
stack[1] = ‘e’;
i = 1;
j = 0;
while (stack[i] != ‘$’)
{
if (stack[i] == s[j])
{
i–;
j++;
}
else
{
switch (stack[i])
{
case ‘e’: stx1 = 0; break;
case ‘b’: stx1 = 1; break;
case ‘t’: stx1 = 2; break;
case ‘c’: stx1 = 3; break;
case ‘f’: stx1 = 4; break;
default:
printf(“ERRORn”);
return 0;
}
switch (s[j])
{
case ‘i’: stx2 = 0; break;
case ‘+’: stx2 = 1; break;
case ‘*’: stx2 = 2; break;
case ‘(‘: stx2 = 3; break;
case ‘)’: stx2 = 4; break;
case ‘$’: stx2 = 5; break;
default:
printf(“ERRORn”);
return 0;
}
if (m[stx1][stx2][0] == ”)
{
printf(“ERRORn”);
return 0;
}
else if (m[stx1][stx2][0] == ‘^’)
{
i–;
}
else
{
i–;
for (k = size[stx1][stx2] – 1; k >= 0; k–)
{
stack[++i] = m[stx1][stx2][k];
}
}
}
}
if (s[j] == ‘$’)
printf(“SUCCESSn”);
else
printf(“ERRORn”);
return 0;
}
9. Write a C program for constructing recursive descent parsing
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define MAX_LEN 100
char lookahead;
char *input;
void advance();
void error();
void match(char expected);
void E();
void E_prime();
void T();
void T_prime();
void F();
void advance()
{
lookahead = *input++;
}
void error()
{
fprintf(stderr, “Error parsing inputn”);
exit(1);
}
void match(char expected)
{
if (lookahead == expected)
advance();
else
error();
}
void E()
{
printf(“E -> T E’n”);
T();
E_prime();
}
void E_prime()
{
if (lookahead == ‘+’)
{
printf(“E’ -> + T E’n”);
match(‘+’);
T();
E_prime();
}
else
{
printf(“E’ -> epsilonn”);
}
}
void T()
{
printf(“T -> F T’n”);
F();
T_prime();
}
void T_prime()
{
if (lookahead == ‘*’)
{
printf(“T’ -> * F T’n”);
match(‘*’);
F();
T_prime();
}
else
{
printf(“T’ -> epsilonn”);
}
}
void F()
{
if (isdigit(lookahead) || isalpha(lookahead))
{
printf(“F -> idn”);
advance();
}
else if (lookahead == ‘(‘)
{
printf(“F -> (E)n”);
match(‘(‘);
E();
match(‘)’);
}
else
{
error();
}
}
int main()
{
char input_string[MAX_LEN];
fgets(input_string, MAX_LEN, stdin);
input = input_string;
advance();
E();
if (lookahead == ” || lookahead == ‘n’)
printf(“Parsing Successfuln”);
else
printf(“Parsing Failedn”);
return 0;
}
10. Write a C program to implement LALR parsing
%{
#include <stdio.h>
#include <stdlib.h>
int yylex(void);
void yyerror(const char *s);
%}
%token NUM PLUS TIMES LPAREN RPAREN END
%%
input :
| input line
;
line : expr END { printf(“Result: %dn”, $1); }
;
expr : term { $$ = $1; }
| expr PLUS term { $$ = $1 + $3; }
;
term : factor { $$ = $1; }
| term TIMES factor { $$ = $1 * $3; }
;
factor : NUM { $$ = $1; }
| LPAREN expr RPAREN { $$ = $2; }
;
%%
int main() {
printf(“Enter expression:n”);
return yyparse();
}
void yyerror(const char *s) {
fprintf(stderr, “Error: %sn”, s);
}
- acd