VIVEKANANDA INSTITUTE OF TECHNOLOGY DEPARTMENT OF COMPUTER SCIENCE AND ENGG.
COMPILER DESIGN LAB
LIST OF EXPERIMENTS: 1. Implementation of token separation. 2. Implementation of symbol table. 3. Implementation of Lexical Analysis in “C” 4. Implementation of Lexical Analysis in “LEX” 5. Implementation of Syntax checking using “LEX” and “YAC” 6. Implementation of Syntax checking in “C” 7. Conversion of Infix to postfix. 8. Evaluating postfix expression using “LEX” 9. Implementation of Intermediate code Generator. 10. Implementation of Operator precedence parser
1. TOKE TOKEN N SEPAR SEPARATIO ATION N AIM:To write a program to implement the token separation operation AlGORITHM: Step 1: Start the program. Step 2: Store the possible keywords ke ywords in an array key[][] and their corresponding byte b yte value in b[]. Step 3: Declare all the variables. Step 4: Declare the file pointer fp for file operation. Step 5: Open a file sym.c in write mode. Step 6: Enter valid data into sym.c file until “#” symbol encountered. Then close the file. Step 7: Open d.c file in read mode.Read the character one by one.
Step 8: If not End of file using switch case check for special symbols.Print s ymbols.Print the special symbol. Step 9: Check whether the string is alphabet or alphanumeric using isalpha() and isalnum() functions. Step 10: If the string is alphabet assign it to variable “a” and compare with keywords in array using strcmp() function. Step 11: If string is keyword print the keyword and its corresponding byte value and copy the string to variable”data” using strcpy (). Step 12: Else copy to variable “sym”. Step 13: Check for the character is constant value using isdigti() function and copy the constant in the variable “val” using strcpy(). Step 14: Print all the datatype, identifier and constant value. Step 15: Stop the program.
PROGRAM: #include<stdio.h> #include<conio.h> #include<string.h> char key[5][10]={"int","float","char","double"}; int b[5]={2,1,4,8}; int main() { int byte; int label; int i,j,n,k=0; char data[10],sym[10],val[10]; char a[20]; char str; FILE *fp; clrscr(); fp=fopen("sym.c","w"); printf("\n enter a valid declarations:"); while((str=getchar())!='#') { fputc(str,fp); } fclose(fp); fp=fopen("d.c","r"); printf("\n______________________________________"); printf("\t\t SYMBOL TABLE\n"); TABLE\n"); printf("\n________________________________________"); printf("\ndata-type\tidentifier\tvalue\tbytes-occupied\n"); printf("\ndata-type\tidentif ier\tvalue\tbytes-occupied\n"); while((str=fgetc(fp))!=EOF) {
enter a valid data: void main() { int a=5; } # TOKEN SEPARATION token no.
token name
1 2
void main
3 4 5 6 7 8 9 10 11
( ) { int a = 5 ; }
token-type a keyword a keyword a special symbol a special symbol a special symbol a keyword an identifier an operator a constant a special symbol a special symbol
RESULT: Thus the program was implemented and verified.
2. SYMBOL TABLE AIM: To write a program to implement the Symbol S ymbol table operation
AlGORITHM: Step 1: Start the program. Step 2: Store the possible keywords ke ywords in an array key [][] and their corresponding co rresponding byte value in b[]. Step 3: Declare all the variables. Step 4: Declare the file pointer fp for file operations. Step 5: Open d.c file in write mode and enter the valid data with ‘#’ symbol at the end of file.Then close the file. Step 6:Open d.c in read mode.Read the character one by one. Step 7: If not end of file, using switch case display the character is special symbol or an operator. Step 8: Check whether the string is alphabet or alphanumeric using isalpha () and isalnum() functions respectively. Step 9: If the string is alphabet assign it to variable “a” and compare with the keywords in array using strcmp () function. Step 10: Then print keyword and its corresponding byte value and copy string to variable “data” using strcpy (). Step 11: Else copy to variable “sym” . Step 12: Check the string is alphabet or digit using isdigit() and isalpha() functions. Step 13: If the string is digit then print the string is constant. Step 14: Take fp to the assigned position. Step 15: Close fp. Step 16: Stop the program.
PROGRAM: #include<stdio.h> #include<conio.h> #include<string.h> char key[5][10]={"int","float","char","double"}; int b[5]={2,4,1,8}; int main() { int byte; int label; int i,j,n,k=0; char data[10],sym[10],val[10];
OUTPUT: enter a valid declarations:int a=5; float f=3.4; double d=6.7; char c='f'; #
________________________ ______________ ______________________________________ SYMBOL TABLE ________________________ ________________ ________________________________________ data-type identifier identifier value bytes-occupied int float double char
a f d c
5 3.4 6.7 f
2 4 8 1
RESULT: Thus the program was implemented and verified.
3. LEXICAL ANALYSIS USING C AIM: To write a program to implement the Lexical analysis using C
AlGORITHM: Step 1: Start the program. Step 2: Include the necessary header files. Step 3: The ctype header file is to load the file with predicate isdigit. Step 4: The define header file defines the buffer size, numerics, assignment operator,relational operator. Step 5: Initialize the necessary variables. Step 6: To return index of new string S,token t using insert() function. Step 7: Initialize the length for every string. Step 8: Check the necessary condition. Step 9: Call the initialize() function.This function loads the keywords into the symbol table. Step 10: Check the conditions such as white spaces,digits,letters and alphanumerics. Step 11: To return index of the entry for string S,or 0 if S is not found using lookup() function. Step 12: Check this until EOF is found. Step 13: Otherwise initialize the token value to be none. Step 14: In the main function if lookahead equals numeric then the value of attribute num is given by the global variable tokenval. Step 15: Check the necessary conditions such as arithmetic operators, parenthesis, identifiers, assignment operators and relational operators. Step 16: Stop the program.
{ int lookahead; char ans; clrscr(); printf("\n Program for lexical analysis:"); initialize(); printf("Enter the expression and put ; at the end\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 parenthesis"); if(lookahead==ID) printf("\n Identifier%s",symtable[tokenval].lexptr); Identifier%s",symtable[tokenval].lexptr); if(lookahead==ASSIGN) printf("\n Assignment Operator"); if(lookahead==REL_OP) printf("\n Relational Operator"); lookahead=lexer(); } }
OUTPUT: Program for lexical analysis: Enter the expression and put ; at the end press ctrl z to terminate void main() Identifiervoid space Identifiermain parenthesis parenthesis int i=69; Identifierintspace Identifieri Assignment Operator Number69
RESULT:
Thus the program was implemented and verified
LEXICAL ANALYSIS USING LEX TOOLS AIM: To write a program to implement the Lexical analysis using LEX
AlGORITHM: Step 1: Create the lex source with lex specification with the extension .l or .ex. Step 2: Check for the identifier whether it is alphabets or numeric character. Step 3: If it find # then print it is a preproccesor directive Step 4: Check for the other keywords such as int, float, cha char, r, double, while, for, do, if, break, continue, void, switch case, long, struct, const, typedef, return(0),else and if it find any of the above display it is a keyword. Step 5: Store it in a variable called yytext Step 6: If it encounters \/\/ print it is acomment Step7: The \{ represents the beginning of clock and /} represents the end of the block Step 8: If it finds “” then print it is a string Step 9: It is encountered upto 0-9 then display it is a nu number mber Step10: Echo is like the prints statement character within the double quotes Step11: If it finds = then print an argument operation Step12: If it find the operators such as <,>=,<= then print it is an relational operator Step13: Then finish the rules section Step14: Include the code section Step15: Open a file if it does do es not match then display could not open the file Step16: The yyin points the opening of current file Step17: The yyout is to check whether the input goes to which file Step18: The yywrap is match of end of file or end of source Step19: If an input is given to lex it will be converted into a c file,lex yy.c Step 20: This can be compiled into an executable file using cc lex.yy.c
PROGRAM: (add.c) #include<stdio.h> void main() { int a,b,c; printf("a="); scanf("%d",&a);
printf("b"); scanf("%d",&b); c=a+b; printf("c=%d",c); getch (); } (lex.l) %{ int COMMENT=0; %} identifier[a-zA-z][a-zA-z0-9]* %% #.* { printf("\n%s is a preprocessor directive",yytext);} directive",yytext);} int | float | char | double | while for | | do | if | break | continue | void | switch | case | long | struct | const | typedef | return | else | goto { printf("\n\t%s is a keyword",yytext); } if[\t]* { printf("\n\t 'if' is a keyword\n\t"); ke yword\n\t"); } \/\/.* { printf("\n\n\t%s is a omment",yytext); } \{ { printf("\nBlock begins"); } \} { printf("\n Block ends"); } radius | area | argv | r| argc { printf("\n%s identifier",yytext); } \".*\" { printf("\n\t %s is a string",yytext); }
[0-9]+ { printf("\n\n\t%s is a number \n",yytext); } \)(\;)? { printf("\n\t");ECHO; p rintf("\n\t");ECHO;printf("\n"); printf("\n"); } \(ECHO; = { printf("\n\t %s is a argument operator",yytext); } \<= | \>= | \< | == | \> printf("\n\t %s is a relational operator",yytext); .|\n; %% int main(int argc,char **argv) { if(argc>1) { FILE *file; file = fopen(argv[1],"r"); if(!file) { printf("Could not open %s\n",argv[1]); exit(0); } yyin=file; } yylex(); printf("\n\n"); return 0; } int yywrap() { return 0; }
OUTPUT: [cse@cselinux cse]$ lex lex.l [cse@cselinux cse]$ cc lex.yy.c [cse@cselinux cse]$ ./a.out add.c #include<stdio.h> is a preprocessor directive
void is a keyword ) Block begins int is a keyword r identifier int is a keyword "a=" is a string ); "%d" is a string ); r identifier int is a keyword "b" is a string ); "%d" is a string ); = is a argument operator r identifier int is a keyword "c=%d" is a string ); ); Block ends [5]+ Stopped [cse@cselinux cse]$
./a.out add.c
RESULT: Thus the program was implemented and verified
4. SYNTAX SYNTAX CHECKING CHECKING USING LEX AND YACC YACC AIM: To write a program to implement the syntax s yntax analyzer using LEX and YA YACC CC
AlGORITHM: Step 1: Lex and yacc can be easily interfaced Step 2: Lex compiler can be used to perform lexical analysis phase Step 3: Create a lex source with lex specification with extension .l Step 4: In lex code we check for letter ie. Alphabets and we check for digit ie.numeric values Step 5: Lex compiler will produce the tokens Step 6: Tokens are used for yacc compiler for syntax analyzing Step 7: In yacc compiler accepts a large class of CFG’s but require a lower level analyzer to recognize input tokens Step 8: In yacc source specifies grammars. i)write the grammar in .y file eg:list:list stat|list error ii)expr:’(‘expr’)’|expr ii)expr:’(‘expr’)’| expr ‘*’ expr|expr’(‘exprexpr|expr’%’expr. Step 9: In main function yyparse() is used to call parser Step 10:yyerror() method is used to handle the errors from yacc Step 11: Compile the code produced by YACC as well as LEX Step 12: Link the object ob ject files to appropriate libraries for executable parser Step 13: Execute the (program)parser
PROGRAM: (srical.y) %{ #include<stdio.h> int regs[26]; int base; %} %start list %token DIGIT LETTER %left '|' %left '&' %left '+' '-' %left '*' '/' '%' %left UMINUS %% list: | list stat '\n' |
} void E1() { if(lookahead=='+'||lookahead=='-'||lookahead=='*'||lookahead=='/') A(lookahead); } void A(char lt) { switch(lt) { case '+': case '-': case '*': case '/': printf("Arithmetic Operator : %c\n",lt); %c\n",lt); lookahead=str[++i]; if(!isalnum(lookahead)) { printf("Syntax Error\n"); exit(0); } break; } }
OUTPUT: [cse@cselinux cse]$ cc –o ex6 ex6.c [cse@cselinux cse]$ ./ex6 Given Grammar E->idE1|numE1 E1->+|-|*|/ Enter the string ending with $ Position+rate*60$ Identifier:position Arithmetic Operator:+ Identifier:rate Arithmetic Operator:* Number:60 Given Expression is correct
RESULT: Thus the program was implemented and verified
6. CONVERS CONVERSION ION OF INFIX TO POST POSTFIX FIX AIM: To write a C program to convert c onvert an infix expression to a p postfix ostfix expression .
ALGORITHM: Step 1: Start the program. Step 2: Include all the required header files. Step 3: Declare a global variable namely lookahead. The datatype of lookahead is integer. Step 4: In the main() function get ge t an infix expression as input from the user and call the expr() function. Step 5: In expr() function perform the following task after calling the term() function. (a)Inside an infinite while loop i.e., while(1) check the operator. (b)If lookahead is a ‘+’ sign then call match(+) and go to step 5. (c)If lookahead is a ‘-’ sign then call match(-) and go to step 5. (d)If the above two conditions are not satisfied then break out of the loop. Step 6:In turn() function the print following tasks, (a)If lookahead is perform a digit then the value of lookahead. (b)Then call the match() function with lookahead as the parameter. (c)Else call the error() function. Step 7:In the error() function print “Syntax Error” and then terminate the program. Step 8:In match() function perform the following tasks, (a)If lookahead = = t then use getchar() to get the input from the user. (b)Else call the error() function. Step 9: Finally display the postfix po stfix expression. Step 10:Terminate the program.
RESULT: Thus the program was implemented and verified
8. EVALUATING POSTFIX EXPRESSION
AIM:
To write a program to evaluate a postfix expression
ALGORITHM: Step1: Start Start the program. Step2: Define a stack of size 100 ant two integer variables sp,stack(stack –size) Step3: Inside the push() function perform the following task. a)If (++sp <(stack-size)then assingn the value of I to stack[sp] b)Else display an error message “Stack overflow” step4: In the pop() function, perform the following task, a)If the value of sp is greater then 0, then pop the last entry out of the stack b)Else display an error message “stack underflow”. Step5: If a digit ie.[0-9] is encountered then push it into the stack. Step6: If an operator ie.[+,*,-,/] is encountered then push it into the stack and apply the operator to the last two entries of the stack Step 7: If a semicolon is encountered then pop the value at the TOS and print that value Step8:If any control sequence ie.[\t\n] is encountered then no action is performed Step9: If any error condition is encountered then display a message “Unexpected”. AUXILLARY ACTION: Step10: In the main() function initialize the variable v ariable sp to -1 and call yylex() function Step11: In the function yywrap() which has no parameters return 1 Step 12: Finally after the required evaluations terminate the program Step13: stop the program
OUTPUT: [basariya@telnet ~]$ ./a.out Please enter the infix_notated expression with single digits 5-3 Compiling to postfix_notated expression: 53Compiling to assembly_notated expression: PUSH5 PUSH3 POP B POP A SUB A,B PUSH A
RESULT: Thus the program was implemented and verified
9. IMPLEMENT IMPLEMENTATION ATION OF INTER INTERMEDIA MEDIATE TE CODE GENERATOR AIM: To write the program to implement the intermediate code generation using C.
ALGORITHM: Step 1:Start the program. Step 2:Include all header files. Step 3:Declare two character array str[10] and stk[10][3]. Step 4:Decalre an array that holds a list of temporary variables. Step 5:Initialise the top of stack to -1 and ntemp to 0. Step 6:Declare a structure 4 members of datatype char. -opr for the operator, arg1[5] and arg2[5] for the two arguments and res[5] for the result. Step 7:In the main() function get the input string from the user and store it in str[]. Step 8:Using for loop the intermediate intermediate code statements can be generated as follows. follows. (a)Initialize the loop variable i to 0. (b)If str[i] is an alphabet then store it in the top of stack and set the next location i.e., stk[top][1] to null. (c)If the above condition is false then store str[5] in s[++n].opr and copy co py the TOS to arg2. (d)If top>-1 then copy TOS to arg1. (e)Copy the temporary variables to res. If i<strlen(str) go to 7.(a).Else go to step 8. Step 9:Finally print the intermediate code in the form of three address code table. Step 10:Terminate the program.
PROGRAM: #include<stdio.h> #include<string.h> Cahr str[10],temp[10][3]={“T1”,”T2”,”T3”,”T4”,”T5”},stk[10][10]; Int top=-1,ntemp=0; Struct st { Char opr; Char arg1[10]; Char arg2[10]; Char res[10]; }s[10]; Int main() {