0% found this document useful (0 votes)
76 views20 pages

Rajalakshmi Institute of Technology Chennai: Department of Computer Science and Engineering

The document describes the implementation of a recursive descent parser in C. The algorithm involves getting an expression from the user, using a lexer function to get tokens and match the lookahead pointer, and defining functions for E(), T(), F() to check the grammar at each level. The program takes an input file, calls the parser function, and uses functions like match(), F(), T(), E() to parse the expression based on the grammar rules and return syntax errors if not valid. It was tested on sample inputs and able to successfully parse the expressions.

Uploaded by

Thyaga Rajan
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
76 views20 pages

Rajalakshmi Institute of Technology Chennai: Department of Computer Science and Engineering

The document describes the implementation of a recursive descent parser in C. The algorithm involves getting an expression from the user, using a lexer function to get tokens and match the lookahead pointer, and defining functions for E(), T(), F() to check the grammar at each level. The program takes an input file, calls the parser function, and uses functions like match(), F(), T(), E() to parse the expression based on the grammar rules and return syntax errors if not valid. It was tested on sample inputs and able to successfully parse the expressions.

Uploaded by

Thyaga Rajan
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 20

RAJALAKSHMI INSTITUTE OF TECHNOLOGY CHENNAI

DEPARTMENT OF COMPUTER SCIENCE AND ENGINEERING

CS2352 PRINCIPLES OF COMPILER DESIGN LAB MANUAL PREPARED BY, R. VELUMADHAVA RAO (AP/CSE)

SEMESTER VI 2012-2013

IMPLEMENTATION OF A LEXICAL ANALYZER IN C


AIM: To write and execute a C program to implement the lexical analyzer.

ALGORITHM: 1. Start the program. 2. Declare the file pointer and necessary variables. 3. Open the input file in the read mode. 4. Use the analyze function to analyze the input program and store the identifiers, keywords and operator on idhd, keyhd, ophd respectively. 5. Stores the tokens in data structure linked lists. 6. Increment the line number of each token and its occurrences. 7. Using the show function print the linked lists in a tabular format. 8. Stop the program.

PROGRAM
#include<stdio.h> #include<conio.h> #include<ctype.h> #include<string.h> #include<stdlib.h> #define SIZE 128 #define NONE -1 #define EOS '\0' #define NUM 256 #define KEYWORD 257 #define PAREN 258 #define ID 259 #define ASSIGN 260 #define REL_OP 261 #define DONE 262 #define MAX 999 char lexemes[MAX]; char buffer[SIZE]; int lastchar = -1; int lastentry = 0; int tokenval=NONE; int lineno=1; struct entry { char *lexptr; int token; }symtable[100]; struct entry

keywords[]={"if",KEYWORD,"else",KEYWORD,"for",KEYWORD,"int",KEYWORD,"float",KEY WORD,"double",KEYWORD,"char",KEYWORD,"struct",KEYWORD,"return",KEYWORD,0,0}; void Error_Message(char *m) {

fprintf(stderr,"line %d: %s",lineno,m); exit(1); } int look_up(char s[]) { int k; for(k=lastentry;k>0;k--) if(strcmp(symtable[k].lexptr,s)==0) return k; return 0; }

int insert(char s[],int tok) { int len; len=strlen(s); if(lastentry+1>=MAX) Error_Message("Symbol Table is Full"); if(lastchar+len+1>=MAX) Error_Message("Lexemes Array is Full"); lastentry++; symtable[lastentry].token=tok; symtable[lastentry].lexptr=&lexemes[lastentry+1]; lastchar = lastchar + len + 1; strcpy(symtable[lastentry].lexptr,s); return lastentry; } void Initialize() { struct entry *ptr; for(ptr=keywords;ptr->token;ptr++) insert(ptr->lexptr,ptr->token); } int lexer() {

int t; int val,i=0; while(1) { t=getchar(); if(t == ' ' || t=='\t'); else if(t=='\n') lineno++; else if(t == '(' || t == ')') return PAREN; else if(t=='<'||t=='>'||t=='<='||t=='>='||t == '!=') return REL_OP; else if(t == '=') return ASSIGN; else if(isdigit(t)) { ungetc(t,stdin); scanf("%d",&tokenval); return NUM; } else if(isalpha(t)) { while(isalnum(t)) { buffer[i]=t; t=getchar(); i++; if(i>=SIZE) Error_Message("compiler error"); } buffer[i]=EOS; if(t!=EOF) ungetc(t,stdin); val=look_up(buffer); if(val==0)

val=insert(buffer,ID); tokenval=val; return symtable[val].token; } else if(t==EOF) return DONE; else { tokenval=NONE; return t; } } } int main() { int lookahead; char ans; printf("\n]t]t Program for Lexical Analysis \n"); Initialize(); printf("\n Enter the expression and put ; at the end"); printf("\n Press Ctrl + Z to terminate... \n"); lookahead=lexer(); while(lookahead!=DONE) { if(lookahead==NUM) printf("\n Number: %d",tokenval); if(lookahead=='+'|| lookahead=='-'|| lookahead=='*'|| lookahead=='/') printf("\n Operator"); if(lookahead==PAREN) printf("\n Parentesis"); if(lookahead==ID) printf("\n Identifier: %s",symtable[tokenval].lexptr); if(lookahead==KEYWORD) printf("\n Keyword");

if(lookahead==ASSIGN) printf("\n Assignment Operator"); if(lookahead==REL_OP) printf("\n Relataional Operator"); lookahead=lexer(); } return 0; }

OUTPUT: Program for Lexical Analysis Enter the expression and put ; at the end Press Ctrl + Z to terminate... 2+3 Number: 2 Operator Number: 3 if(a<b) a=a+b; Keyword Parenthesis Identifier: a Relational Operator Identifier: b Parenthesis Identifier: a Assigment Operator Identifier: a Operator Identifier: b ^Z

RESULT:
Thus the implementation of lexical analyzer was successfully done.

IMPLEMENTATION OF A LEXICAL ANALYZER USING LEX TOOL


AIM: To implement the lexical analyzer using lex tool for a subset of C language. ALGORITHM: 1. Start the program. 2. Declare necessary variables and creates token representation using Regular. 3. Print the pre processor or directives, keywords by analysis of the input program. 4. In the program check whether there are arguments. 5. Declare a file and open it as read mode. 6. Read the file and if any taken in source program matches with RE that all returned as integer value. 7. Print the token identified using YYdex() function. 8. Stop the program.

PROGRAM
%{ %} identifier[a-zA-Z][a-zA-Z0-9]* %% #.* {printf("\n%s is a preprocessor directive",yytext);} int | float | char | double | while | do | if | break | continue | void | switch | return | else | goto {printf("\n%s is a keyword",yytext);} {identifier}\( {printf("\n function %s",yytext);} \{ {printf("\nblock begins");} \} {printf("\nblock ends");} \( {printf("\n");ECHO;} {identifier}(\[[0-9]*\])* {printf("\n%s is an identifier",yytext);} \".*\" {printf("\n %s is a string ",yytext);} [0-9]+ {printf("\n%s is a number",yytext); } \<= | \>= | \< | \> | \== {printf("\n %s is a relational operator",yytext);}

\= | \+ | \- | \/ | \& | % {printf("\n %s is a operator",yytext);} .| \n; %% int main(int argc,char **argv) { FILE *file; file=fopen("inp.c","r"); if(!file) { printf("could not open the file!!!"); exit(0); } yyin=file; yylex(); printf("\n\n"); return(0); } int yywrap() { return 1; }

INPUT FILE:
#include<stdio.h> void main() { int a,b,c; printf("enter the value for a,b"); scanf("%d%d",&a,&b)'; c=a+b; printf("the value of c:%d",&c); }

OUTPUT:
[3cse01@localhost ~]$ lex ex3.l [3cse01@localhost ~]$ cc lex.yy.c [3cse01@localhost ~]$ ./a.out #include<stdio.h> is a preprocessor directive void is a keyword function main( block begins int is a keyword a is an identifier b is an identifier c is an identifier function printf( "enter the value for a,b" is a string function scanf( "%d%d" is a string & is a operator a is an identifier & is a operator b is an identifier c is an identifier = is a operator a is an identifier + is a operator b is an identifier function printf( "the value of c:%d" is a string & is a operator c is an identifier block ends

RESULT: Thus the program to implement the lexical analyzer using lex tool for a subset of C language was implemented and verified.

IMPLEMENTATION OF A RECURSIVE DESCENT PARSER


AIM: To implement a recursive descent parser in a C program.

ALGORITHM: 1. Start the program. 2. Get the expression from the user and call the parser() function. 3. In lexer() get the input symbol and match with the look ahead pointer and then return the token accordingly. 4. In E(), check whether the look ahead pointer is + or - else return syntax error. 5. In T(),check whether the look ahead pointer is * or / else return syntax error. 6. In F(),check whether the look ahead pointer is a member of any identifier. 7. In main(), check if the current look ahead points to the token in a given CFG it doesnt match the return syntax error.

PROGRAM

#include<stdio.h> #include<string.h> #include<stdlib.h> #define DONE 260 #define NUM 257 #define ID 259 void E(); void T(); void F(); void parser(); int lexer(); void match(int); void parsex(); int i=0,flag=9,lkahd; char inp[75]; int cnt=-1; int main() { int i=-1; char c; FILE *fp; fp=fopen("ep1.text","rt"); while((c=fgetc(fp))!=EOF) { inp[i++]=c; } inp[i]=EOF;

parser(); }

int lexer() { int t; while(1) { t=inp[cnt++]; if(t==' '||t=='\t'||t=='\n') ; else if(t=='+'||t=='-'||t=='*'||t=='/') { printf("arithmetic operator %c\n",t); return t; } else if(isdigit(t)) { printf("\n number: %c\n",t); return NUM; } else if(isalpha(t)) { printf("\n identifier: %c\n",t); return ID; } else if(t==EOF) return DONE; else return t; }} void parser() { lkahd=lexer();

while(lkahd!=DONE) { E(); match(';'); } if(lkahd==DONE) parsex(); } void match(int t) { if(lkahd==t) lkahd=lexer(); else return; } void F() { switch(lkahd) { case '(': match('('); E(); match(')'); break; case NUM: match(NUM); break; case ID: match(ID); break; default:{ printf("syntax error"); flag=7; }}}

void T() { int t; F(); while(1) { switch(lkahd) { case '*': t=lkahd; match(lkahd); F(); continue; case '/': t=lkahd; match(lkahd); F(); continue; default: return; }}} void E() { int t; T(); while(1) { switch(lkahd) { case '+': t=lkahd; match(lkahd); T(); continue;

case '-': t=lkahd; match(lkahd); T(); continue; default: return; }}} void parsex() { if(flag!=7) printf("parse seccessfull\n"); else printf("parse successfull\n errors found\n"); exit(0); }

INPUT FILE: (a+b)*(c/d)-g; 1+5; 5-3; a+2;

OUTPUT: [3cse01@localhost ~]$ cc ex4.c [3cse01@localhost ~]$ ./a.out identifier: a arithmetic operator + identifier: b arithmetic operator * identifier: c arithmetic operator / identifier: d arithmetic operator identifier: g number: 1 arithmetic operator + number: 5 number: 5 arithmetic operator number: 3 identifier: a arithmetic operator + number: 2 parse seccessfull

RESULT: Thus the program to implement the recursive descent parser was implemented and verified.

You might also like