Compiler Lab Manual Final E-content

April 20, 2017 | Author: PRISTUniversity | Category: N/A
Share Embed Donate


Short Description

Download Compiler Lab Manual Final E-content...

Description

PRIST UNIVERSITY (Estd. u/s 3 of UGC Act, 1956)

_________________________________________________________________________________

11150L66-Compiler Design Lab Manual III Year / VI Semester PREPARED BY R.BHAVANI, ASSISTANT PROFESSORS CSE DEPARTMENT

November-2013 FACULTY OF ENGINEERING AND TECHNOLOGY

CONTENTS

S.No

Title

Page No

1.

Implement a lexical analyzer in “C”

11

2.

Implement a lexical analyzer in “C”

15

3.

Use LEX tool to implement a lexical analyzer

18

4.

Implement a recursive descent parser for an expression grammar that generates arithmetic expressions with digits, + and *.

22

5.

Use YACC and LEX to implement a parser for the same grammar as given in previous problem

27

6.

Write semantic rules to the YACC program and implement a calculator.

31

7.

Implement the front end of a compiler that generates the three address code for a simple language.

35

8.

Implement the front end of a compiler that generates the three address code for a simple language.

35

9.

Implement the back end of the compiler and produces the assembly language instructions

39

10. Implement the back end of the compiler which takes the three address code generated and produces the assembly language instructions.

39

11. Implementing a Shift reduce parser.

45

12. Sample LEX program

51

11150L66/Compiler Design Lab

III year/VI Sem

THEORY OF PRACTICE Lexical Analyzer •Lexical Analyzer reads the source program character by character to produce tokens. •Normally a lexical analyzer doesn‟t return a list of tokens at one attempt; it returns a token when the parser asks a token from it.

The Role of the Lexical Analyzer  Read input characters  Group them into lexemes  Produce as output as a sequence of tokens ◦ Which in-turn used as input for the syntactical analyzer  Interact with the symbol table ◦ Insert identifiers  It stripes out ◦ comments ◦ White spaces: blank, new line, tab… ◦ other separators  Correlates error messages generated by the compiler with the source program ◦ By keep tracking the number of new lines seen ◦ And associates a line number with each error message

Tokens, Patterns, Lexemes  Token - pair of: ◦ Token name – abstract symbol representing a kind of lexical unit  keyword, identifier, … ◦ Optional attribute value  Pattern ◦ Description of the form that the lexeme of a token may take ◦ e.g.  For a keyword the pattern is the character sequence forming that keyword  For identifiers the pattern is a complex structure that is matched by many strings  Lexeme

◦ A sequence of characters in the source program matching a pattern for a token

1

Prepared by R.Bhavani, AP/CSE, PRIST University.

11150L66/Compiler Design Lab

III year/VI Sem

Shift-Reduce Parser: •

There are four possible actions of a shift-parser action: – Shift : The next input symbol is shifted onto the top of the stack. – Reduce: Replace the handle on the top of the stack by the non-terminal. – Accept: Successful completion of parsing. – Error: Parser discovers a syntax error, and calls an error recovery routine. Initial stack just contains only the end-marker $. The end of the input string is marked by the end-marker $.

• •

A Stack Implementation of A Shift-Reduce Parser Stack $ $id $F $T $E $E+ $E+id $E+F $E+T $E+T* $E+T*id $E+T*F $E+T $E

Input id+id*id$ +id*id$ +id*id$ +id*id$ +id*id$ id*id$ *id$ *id$ *id$ id$ $ $ $ $

Action shift reduce by F  id reduce by T  F reduce by E  T shift shift reduce by F  id reduce by T  F shift shift reduce by F  id reduce by T  T*F reduce by E  E+T accept

Recursive-Descent Parsing (uses Backtracking) •Backtracking is needed. It tries to find the left-most derivation – Recursive-Descent Parsing • Backtracking is needed (If a choice of a production rule does not work, we backtrack to try other alternatives.) • It is a general parsing technique, but not widely used. • Not efficient

2

Prepared by R.Bhavani, AP/CSE, PRIST University.

11150L66/Compiler Design Lab

III year/VI Sem

Operator Precedence Parsing: • Form of Shift/Reduce parsing • Two important properties for these shift reduce Parsers is that ε (epsilon) does not appear on the right side of any production and no production has two adjacent non terminals (NT). E -> E + E T -> + T T// wrong production, because it has 2 adjacent NT. This allows us to find handles

Precedence • We need to define three different precedence relations between pairs of terminals .They look like >, +TE'"); advance(); t(); eprime(); } else printf("\n \t \t E'-->e"); } void t() { printf("\n \t \t E'-->FT'"); f(); tprime(); } void tprime() 23

Prepared by R.Bhavani, AP/CSE, PRIST University.

III year/VI Sem

11150L66/Compiler Design Lab

{ if(ipsym[ipptr]=='*') { printf("\n \t \t E'-->*FT'"); advance(); f(); tprime(); } else printf("\n \t \t T'-->e"); } void f() { if((ipsym[ipptr]=='i')||(ipsym[ipptr]=='I')) { printf("\n\t\tF-->i"); advance(); } else if(ipsym[ipptr]=='c') { advance(); e(); if(ipsym[ipptr]==')') { advance(); printf("\n\t\tF-->(E)"); } } else { printf("\n\t syntax error"); getch(); exit(1); } } void advance() { ipptr++; } void main() 24

Prepared by R.Bhavani, AP/CSE, PRIST University.

III year/VI Sem

11150L66/Compiler Design Lab

III year/VI Sem

{ int i; clrscr(); printf("\n\t\tINPUT"); printf("\n\t\tGrammar without error recursion"); printf("\n\t\tE-->TE'\n\t\tE'-->+TE'|e\n\t\tT-->FT'"); printf("\n\t\tT'-->*FT'|e\n\t\tF-->(E)|i"); printf("\nENTER THE IP EXPRESSION"); gets(ipsym); printf("\n\t\toutput"); printf("\n sequence of production rules"); e(); for(i=0;iTE' E'-->+TE'|e T-->FT' T'-->*FT'|e F-->(E)|i ENTER THE IP EXPRESSION i+i Output sequence of production rules E-->TE' E'-->FT' F-->i T'-->e T-->+TE' E'-->FT' F-->i T'-->e E'-->e

RESULT: Thus the program to implement the recursive descent parser was implemented and input strings were parsed.

26

Prepared by R.Bhavani, AP/CSE, PRIST University.

11150L66/Compiler Design Lab

III year/VI Sem

Using LEX and YACC to implement lexical analyzer

EX: NO: 5 DATE:

AIM: To write a c program to implement the lexical analyzer using LEX and YACC tool.

ALGORITHM:

27



Start the program



Open a file seven.c in read and include the yylex() tool for input scanning.



Define the alphabets, numbers and identifiers.



Print the preprocessor, function, keyword using yytext.lex tool.



Print the relational, assignment and all the operator using yytext() tool.



Also scan and print where the loop ends and begins.



Stop the program.

Prepared by R.Bhavani, AP/CSE, PRIST University.

11150L66/Compiler Design Lab

III year/VI Sem

PROGRAM: IMPLEMENTATION OF LEXICAL ANALYSER USING LEX & YACC // File name is lexical.l %% #.* {printf("\n %s is a PREPROCESSOR DIRECTIVE",yytext);} int | float | char | double | while | for | do | if | break | continue | void | switch | case | long | struct | scanf | printf | const | typedef | return | else | goto {printf("\n\t %s is a KEYWORD",yytext);} \< | \> | \= | \== | \!= {printf("\n\t %s is RELATIONAL OPERATOR",yytext); } \= {printf("\n\t %s is ASSIGNMENT OPERATOR",yytext);} \+ | \- | \* | \/ | \% {printf("\n\t %s is ARITHMETIC OPERATOR",yytext);} \".*\" {printf("\n\t %s is a string",yytext);} [0-9]+ {printf("\n\t %s is a NUMBER",yytext);} [a-zA-Z][a-zA-Z0-9]* {printf("\n\t %s is a IDENTIFIER",yytext);} \{ {printf("\n BLOCK BEGINS");} \} {printf("\n BLOCK ENDS");} \/\*.*\*\/ printf("\n %s is COMMENT",yytext); [\t]; 28

Prepared by R.Bhavani, AP/CSE, PRIST University.

11150L66/Compiler Design Lab

%% int main(int argc,char **argv) { if(argc>1) { FILE *f; f=fopen(argv[1],"r"); if(!f) { printf("could not open %s\n",argv[1]); exit(0); } yyin=f; } yylex(); } INPUT: #include void main() { int a,b,c; printf("enter the a "); scanf("%d%d",&a,&b); c=a+b; getch(); }

29

Prepared by R.Bhavani, AP/CSE, PRIST University.

III year/VI Sem

11150L66/Compiler Design Lab

III year/VI Sem

OUTPUT: $ lex lexical.l $ cc lex.yy.c –ll $ ./a.out seven.c #include is a PREPROCESSOR DIRECTIVE void is a KEYWORD main is a IDENTIFIER BLOCKS BEGINS int is a KEYWORD a,b,c are IDENTIFIER printf is a KEYWORD scanf is a KEYWORD BLOCK ENDS

RESULT: Thus the program for implementation of a lexical analyzer using LEX and YACC tools were successfully done.

30

Prepared by R.Bhavani, AP/CSE, PRIST University.

11150L66/Compiler Design Lab

EX: NO: 6

III year/VI Sem

IMPLEMENTATION OF SIMPLE CALCULATOR USING LEX and YACC

DATE:

AIM: To write LEX and YACC program for implementing calculator using LEX and YACC tools.

ALGORITHM: 

Start the program.



In LEX program declare the identifier for log, cos, sin, tan and memory.



Identify the identifier and return id to parser.



In YACC program declare the possible symbol type, which are the tokens which are returned by LEX.

31



Define precedence and associativity.



Define rule in CFG for non terminal.



In main() get the expression from user and print the output.



Stop the program.

Prepared by R.Bhavani, AP/CSE, PRIST University.

11150L66/Compiler Design Lab

PROGRAM: //File name: calc.yacc %{ #include int regs[26]; int base; %} %start list %token DIGIT LETTER %left '|' %left '&' %left '+' '-' %left '*' '/' '%' %left UMINUS /*supplies precedence for unary minus */ %% /* beginning of rules section */ list: /*empty */ | list stat '\n' | list error '\n' { yyerrok; } ; stat: expr { printf("%d\n",$1); } | LETTER '=' expr { regs[$1] = $3; } ; expr: '(' expr ')' { $$ = $2; } | expr '*' expr { $$ = $1 * $3; } | expr '/' expr { $$ = $1 / $3; } | expr '%' expr { $$ = $1 % $3; } | 32

Prepared by R.Bhavani, AP/CSE, PRIST University.

III year/VI Sem

11150L66/Compiler Design Lab expr '+' expr { $$ = $1 + $3; } | expr '-' expr { $$ = $1 - $3; } | expr '&' expr { $$ = $1 & $3; } | expr '|' expr { $$ = $1 | $3; } | '-' expr %prec UMINUS { $$ = -$2; } | LETTER { $$ = regs[$1]; } | number ; number: DIGIT { $$ = $1; base = ($1==0) ? 8 : 10; } | number DIGIT { $$ = base * $1 + $2; } ; %% main() { return(yyparse()); } yyerror(s) char *s; { fprintf(stderr, "%s\n",s); } yywrap() { return(1); } 33

Prepared by R.Bhavani, AP/CSE, PRIST University.

III year/VI Sem

11150L66/Compiler Design Lab

III year/VI Sem

PROGRAM: // File name: calc.lex

%{ #include #include "y.tab.h" int c; extern int yylval; %} %% " " ; [a-z] { c = yytext[0]; yylval = c - 'a'; return(LETTER); } [0-9] { c = yytext[0]; yylval = c - '0'; return(DIGIT); } [^a-z0-9\b] { c = yytext[0]; return(c); }

OUTPUT: $ lex calc.lex $ yacc -d calc.yacc $ cc y.tab.c lex.yy.c $ mv a.out calculate $ calculate m=45 m+10 55

RESULT: Thus the program for implementing calculator using LEX and YACC tools was successfully done.

34

Prepared by R.Bhavani, AP/CSE, PRIST University.

11150L66/Compiler Design Lab

EX NO:7 & 8:

III year/VI Sem

IMPLEMENTATION OF THE FRONT END OF COMPILER

DATE:

AIM: To Write a C program for implementation of the front end of compiler.

ALGORITHM: STEP 1: The input is a normal c program. STEP 2: It is given as a text file. STEP 3: The front end of the compiler has task of converting the source program into intermediate code. STEP 4: Intermediate code syntax tree, three address code (or) Post fix Notation. STEP 5: The backtracking process is involved here to produce the Intermediate code. STEP 6: Thus the intermediate code is generated for the given input.

35

Prepared by R.Bhavani, AP/CSE, PRIST University.

11150L66/Compiler Design Lab

III year/VI Sem

PROGRAM: IMPLEMENTATION OF FRONT END OF COMPILER //file name is front.c #include #include #include void main() {char pg[100][100],str1[24]; int tem=-1,ct=0,i=-1,j=0,j1,pos=-1,t=-1,flag,flag1,tt=0,fg=0; clrscr(); printf("Enter the codings \n"); while(i>-2) {i++; lab1: t++; scanf("%s",&pg[i]); if((strcmp(pg[i],"getch();"))==0) {i=-2; goto lab1;}} printf("\n pos \t oper \t arg1 \t arg2 \tresult \n"); while(j
View more...

Comments

Copyright ©2017 KUPDF Inc.
SUPPORT KUPDF