1. Develop a lexical analyzer to recognize a few patterns in PASCAL and C. (Ex. identifiers, constants, comments, operators etc.

)
#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”,KEYWORD,”double”,KEYWORD,”char”,KEYWORD, “struct”,KEYWORD,”return”,KEYWORD,0,0}; void Error_Message(char *m) { fprint(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(chars[],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[lastcher+1]; lastchar = lastchar + len + 1; strcpy(smtable[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; } } } void main() { int lookahead; char ans; clrscr(); 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(); } }

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

int tokenval=DONE. int token.KEYWORD. for(k=lastentry.2. char buffer[SIZE].KEYWORD."line %d:%s\n". void errormsg(char *m) { fprintf(stderr. } int lookup(char s[]) { int k. Develop a recursive decent parser #include<stdio."return".m).h> #define #define #define #define #define #define #define #define SIZE 128 NONE -1 EOS '\0' NUM 257 KEYWORD 258 ID 259 DONE 260 MAX 999 char lexemes[MAX]."float".KEYWORD.lexptr. return 0.KEYWORD.KEYWORD.s)==0) return k. int lookahead.h> #include<ctype. 0. struct entry keywords[]={"if"."for".KEYWORD.h> #include<stdlib. int lastchar=-1.h> #include<string. exit(1)."double".0}. "int". int lineno=1. struct entry { char *lexptr.k=k-1) if(strcmp(symtable[k]. "char". } int insert(char s[]. }symtable[100].k>0. int lastentry=0."struct".KEYWORD.KEYWORD.int tok) { ."else".KEYWORD.lineno.

return symtable[val]. return NUM.ptr++) insert(ptr->lexptr.token=tok.s). for(ptr=keywords. if(lastentry+1>=MAX) errormsg("symtable is full"). return lastentry. else if(t=='\n') lineno=lineno+1. } void initialise() { struct entry *ptr.ptr->token. while(1) { t=getchar().token. i=i+1. symtable[lastentry]. } buffer[i]=EOS.ID). } else if(isalpha(t)) { while(isalnum(t)) { buffer[i]=t. if(t==' '||t=='\t').stdin).lexptr=&lexemes[lastchar+1]. scanf("%d".i=0. val=lookup(buffer).stdin). lastchar=lastchar+len+1. } int lexer() { int t. t=getchar(). if(lastentry+len+1>=MAX) errormsg("lexemes array is full"). lastentry=lastentry+1.int len.lexptr. symtable[lastentry].ptr->token). if(val==0) val=insert(buffer. else if(isdigit(t)) { ungetc(t. } else if(t==EOF) . strcpy(symtable[lastentry]. int val.&tokenval). tokenval=val. len=strlen(s). if(i>=SIZE) errormsg("compile error"). if(t!=EOF) ungetc(t.

else printf("\n token:%d tokenval %d". case NUM: display(NUM. while(1) { switch(lookahead) .t). else errormsg("syntax error"). return t. void F() { void E().symtable[tval]. break.tokenval).tokenval).tval). E().return DONE. } void display(int t. match(ID). match(NUM). switch(lookahead) { case '(': match('('). F(). case ID: display(ID. else if(t==NUM) printf("\n number %d". default: errormsg("syntax error"). } tokenval=NONE.int tval) { if(t=='+'||t=='-'||t=='*'||t=='/') printf("\n arithmetic operator %c". match(')'). } } void T() { int t. else { } } } void match(int t) { if(lookahead==t) lookahead=lexer(). break. else if(t==ID) printf("\n identifier:%s".t.tokenval). break.lexptr).

'). continue. F(). match('.NONE). case '-': t=lookahead. while(lookahead!=DONE) { E(). T(). } } } void parser() { lookahead=lexer(). display(t.NONE). clrscr(). display(t. display(t. match(lookahead). default: return.NONE). match(lookahead). } } int main() { char ans.NONE). default: return. match(lookahead). } } } void E() { int t. match(lookahead).{ case '*': t=lookahead. T(). F(). continue. case '/': t=lookahead. T(). continue. . continue. display(t. while(1) { switch(lookahead) { case '+': t=lookahead.

printf("\n \t \t Program for recursive decent parsing"). parser(). initialise(). return 0. number 2 number 3 number 4 arithmetic operator * arithmetic operator + 2+3*4+5. at the end Press CTRL + Z to terminate 2+3*4. number 2 number 3 number 4 arithmetic operator * arithmetic operator + number 5 arithmetic operator + a-b. identifier a identifier b arithmetic operator – +1 Line7: syntaxerror .at the end \n Press CTRL + Z to terminate"). } OUTPUT: Program for recursive decent parsing Enter the expression & place . printf("enter the expression & place.

h> int nIndex=0.h> #include<string. %} %union { char sym. char opera.return NUMBER.l */ %{ #include<stdio.} {LETTER} {yylval.3. char operand2. struct InterCode { char operand1.} {return yytext[0].} \n %% /* Program name: intcode.’ .y */ {return 0. %} NUMBER [0-9]+ LETTER [a-zA-Z]+ %% {NUMBER} {yylval. }. } %token <sym> LETTER NUMBER %type <sym> expr %left ‘-’ ‘+’ %right ‘*’ ’/’ %% statement: LETTER ‘=’ expr ‘. Write a program for generating for various intermediate code forms: ● Three address code ● Quadruple /* %{ #include”y.} Program name: intcode.h” extern char yyval.tab.sym=(char)yytext[0].return LETTER.sym=(char)yytext[0].

(char)$3.char operand2. while(nCnt<nIndex) { printf(“%c : =\t”. } ThreeAddressCode() { int nCnt=0. if(isAlpha(Code[nCnt]]. else .} |expr ‘*’ expr {$$ = AddToTable((char)$1.Code[nCnt]. Code[nIndex].operand2=operand2. else printf(“%c\t”. temp++.Code[nCnt]. char temp =’A’. return temp.temp). Code[nIndex].(char)$3.} .(char)$3. printf(“\n\n\t THREE ADDRESS CODE\n\n”).’+’). temp++.} |expr ‘-’ expr {$$ = AddToTable((char)$1.(char)$3. expr :expr ‘+’ expr {$$ = AddToTable((char)$1. exit(0).’*’).} | expr ‘.opera=opera.opera).s). if(isAlpha(Code[nCnt]].} | LETTER {$$=(char)$1.char opera) { char temp = ’A’.operand1)) printf(“%c\t”. Code[nIndex]. printf(“%c\t”.Code[nCnt]. char AddToTable(char operand1.operand2).temp).’/’).} |expr ‘/’ expr {$$ = AddToTable((char)$1.) | NUMBER {$$=(char)$1. %% yyerror(char *s) { printf(“%s”.’=’).} |’(‘expr’)’ {$$=(char)$2.operand2)) printf(“%c\t”.’-’).(char)$3.{AddToTable((char)$1. nIndex++.’ .operand1=operand1. } struct InterCode Code[20].operand1).

nCnt++. } } void Quadruples() { int nCnt=0.operand1)) printf(“%c\t”. temp++. nCnt++.operand2).opera).Code[nCnt].nCnt.Code[nCnt].operand1).temp). yyparse(). Quadruples(). temp++.temp). if(isAlpha(Code[nCnt]]. else printf(“%c\t”. while(nCnt<nIndex) { printf(“\n(%d)\t%c\t”. char temp =’A’. } .printf(“%c\t”.operand2)) printf(“%c\t”. printf(“%c\t”.Code[nCnt]. printf(“\n”). printf(“\n ID OPERATOR OPERAND1 OPERAND2 RESULT\n”). if(isAlpha(Code[nCnt]]. ThreeAddressCode(). printf(“\n\n\t QUADRUPLES\n”).temp). } } main() { printf(“\nEnter The Expression”). else printf(“%c\t”. } yywrap() { return 1. temp++.temp).

out Enter The Expression: a=(b)+(c*d)/e THREE ADDRESS CODE c* d B/ e b+ B a= B B:= C:= D:= E:= QUADRUPLES ID OPERATOR OPERAND1 OPERAND2 RESULT (0) * c d B (1) / B e C (2) + b B D (3) = a B E .Output: [root@localhost]# lex intcode.l [root@localhost]# yacc -d intcode./a./a. THREE ADDRESS CODE d/ e c* B b+ B a= B B:= C:= D:= E:= QUADRUPLES ID OPERATOR OPERAND1 OPERAND2 RESULT (0) / d e B (1) * c B C (2) + b B D (3) = a B E [root@localhost]# .out Enter The Expression: a=b+c*d/e.y [root@localhost]# .

top]='$'. } . char polish[30].input).h> #include<string. for(i=0. int incoming(char ch). } if(instack(st. int i.s[st.s[st. char pop(). while(instack(st.h> struct stack {char s[30]. scanf("%s". clrscr().i++) { ch =input[i].top])>incoming(sh)) { polish[j]=pop(). getch(). Write a program to generate the intermediate code in the form of Polish Notation #include<stdio. j=0. st. void input_to_code(char infix[30]). printf("\n Enter an input in the form of expression "). void main() { char input[30]. void push(char item). int top. else pop(). int instack(char ch). } void input_to_code(char input[30]) { st.4.top])!=incoming(ch)) push(ch).input[i]!='\0'.h> #include<conio. }st. strrev(input).top=-1. input_to_code(input). char ch.h> #incldue<stdlib.j. j++.s[st.

printf("\n The Polish Notation is %s". case '$':priority=-1.//when it is operand } return priority. } int incoming(char ch) { int priority. } return priority. case '(':priority=0.//when it is operand break. switch(ch) { case ')':priority=0. break. case '+': case '-':priority=1. switch(ch) { case '+': case '-':priority=2. break. case '/':priority=4. break. break.while((ch=pop()!='$') { polish[j]=ch. case ')':priority=9. default:priority=8.polish). j++. break. case '*'. } . break case '^':priority=6.. } int instack(char ch) { int priority. break case '^':priority=5. } polish[j]='\0. case '/':priority=3. case '*'. break. strrev(polish). default:priority=7. break. break.

return e.void push(char item) { st.top].top++.top--. } char pop() { char e.s[st.s[st. } Output: Enter an input in the form of expression (a+b)*(c-d) The polish notation is *+ab-cd . e=st. st. st.top]=item.

Display”): printf (“\n3. printf (“\n1. .Delete an element from list”). deletion. break. Write a program to Simulate Heap storage allocation strategy /************************************************************ Program to perform various operations such as creation. case 5:exit(0).5.h> #include<conio.Create”): printf (“\n2. struct Heap *next. do { clrscr(). break. case 4:dele(&head). case 3:head=insert(head). void main() { /*local declarations*/ int choice. display of heap *************************************************************/ #include<stdio. printf(“\n Program to perform various operations on heap using dynamic memory management”). void display(node *). node *insert(node *). node *create().Quit”).Insert an element in a list”). scanf(“%d.int). switch(choice) { case 1:head=create(). void dele(node **). printf (“\n5. break.h> #define TRUE 1 #include FALSE 0 typedef struct Heap { int data. printf (“\n Enter Your Choice(1-5)”). break. }node.val. insertion. case 2:display(head). node *head.h> #include<stdlib. printf (“\n4. node *search(node *. char ans. head=NULL.&choice”).

temp=new.*new. printf(“\nThe list is created”).default:clrscr(). } /*The create function creates a list of allocated node *Input:None *Output:Retyurns a pointer to head of list *Parameter Passing Methopd:Node **/ node *create() { node *temp. getch(). getch(). printf(“Invalid Choice. new-> data=val. if(new==NULL) printf(“\n Memory is not allocated”). flag=TRUE. int val.* head. char ans=’y’. } }while(choice!=5).&val). } printf(\nDo you want to enter more elements?(y/n)”). return head. ans=getch(). node *get_node(). if (flag==TRUE)/* Executed only for the first time*/ { head=new. } .Try again”). temp=head. /*allocate new node*/ new =get_node(). }while(ans= = ‘y’). temp=NULL. } else { /*temp keeps track of the most recently created node*/ temp->next=new. clrscr(). /*head is the first node in the heap*/ flag=FALSE. /*flag to indicate whether a new node is created for the first time or not*/ do { printf(“\n Enter the Element”). scanf(“%d”.flag.

node *get_node() { node *temp. temp=temp->next. Allocation function temp->next=NULL. } print(“NULL”). //using the mem. int found. return temp. if (temp= =Null) { . } while(temp!= NULL) { printf(“%d->”. temp=(node*)malloc(sizeof(node)). getch(). } /* *The search function *Input: Address of the starting node and the element which is *to be searched *Output:Searches for the element in list *If found returns pointer to that node Otherwise NULL *Parameter passing Method:call by value *Called by:main *Calls:None **/ node *search(node *head.temp-> data). if(temp= =NULL) { printf(“\n The list is empty\n”). clrscr(). getch(). temp=head. return.int key) { node*temp. clrscr(). } /* *The display function *Input:Address of the first node of the list *Output:Displays the list of allocated nodes *Parameter Passing Method : call by value *Called by main **/ void display(node*head) { node *temp. temp=head.

printf(“The linked list is empty\n”). printf(“\n”1. return NULL. While(temp!= NULL && found= =FALSE) { if(temp->data != key) temp = temp->next. } else printf(“\n The Element is not present in the list\n”). } found=FALSE. } /* *The insert function *Input: Address of starting node of the list *Output:inserts element into the list *Parameter Passing Methods: call by value *Called by : main *Calls : search() **/ node *insert(node *head) { int choice. else found = True. break. case2:insert_after (head). return temp. printf(“\n”1.Enter your choice for insertion of node ”). } if(found == TRUE) { printf(“\n The Elements is present in the list”\n). clrscr(). case2:insert_last(head). break. printf(“\n”1.Insert a node as a head node”).Insert a node as a last node”). break. void insert_last(node*). printf(“\n”1. getch(). node *insert_head(node*).&choice). getch().Insert a node as at the intermediate position in the list ”). scanf(“%d”. void insert_after(node*). switch(choice) { case 1:head = insert_head(head). return NULL. . getch().

else { temp=head. temp=head. node *New. printf(“Enter the element after which you want to insert ”). } return head.*temp. scanf(“%d”.*temp.} return head. New->next = temp. } } /*Insertion of node at intermediate position*/ void insert_after(node *head) { int key.&New->data). printf (“\n Enter the element which you want to insert ”). if(head == NULL) { head = New. scanf(“%d”. New = get_node(). head= New. } else { temp=head. if(head == NULL) head = New.&New->data). .*temp. } /*Insertion of node at last position*/ void insert_last(node *head) { node *New. printf (“\n Enter the element which you want to insert ”). New->next=NULL.&key). New = get_node(). } /*Insertion of node at first position*/ node *insert_head(node*head) { node *New. while(temp->next!=NULL) temp=temp->next. scanf(“%d”. New = get_node(). temp->next=New.

scanf(“%d”.*prev. int flag. return. if(temp == NULL) return NULL. New->next=temp->next. while(temp!=NULL && !flag) { if(temp->data!=val) { prev = temp. } and the elemnt to be the list previous node otherwise NULL by value . flag = FALSE. } else temp=temp->next.int val) { node*temp. prev = NULL. else return NULL. } else flag = TRUE. } if(flag) /*if Flag is true*/ return prev. temp = head. temp->next=New. temp = temp->next.&New->data). }while(temp!=NULL). } /* *The get prev function *Input: Address of starting node *searched *Output:looks for the element in *If found returns pointer to the *Parameter Passing Methods: call *Called by : dele() *Calls : none **/ node *get_prev(node *head.do { if(temp->data==key) { printf (“Enter element which you want to insert ”).

Dellocation function } printf(“\n”The Element is deleted\n”). getch(). temp=*head./* *The get prev function *Input: Address of starting node *searched *Output:looks for the element in *If found returns pointer to the *Parameter Passing Methods: call *Called by : dele() *Calls : none **/ and the elemnt to be the list previous node otherwise NULL by value void dele(node **head) { int key. if(prev != NULL) { prev ->next = temp-> next.key). printf("\nENTER the Element you want to delete:"). scanf("%d".&key). } else { *head = temp->next. } } . free(temp). temp= search(*head. getch(). if(temp !=NULL) { prev = get_prev(*head. // using the mem. clrscr().*temp.key). free(temp). node *New. return. } clrscr(). clrscr(). if (temp== NULL) { printf (“\n The list is empty\n ”).

1. Insert an element in a list 4. Create 2.Output: Program to perform various operations on heap using Dynamic memory management. Display 3. Create 2. Display 3. 1. Delete an element from list 5. Create 2. Delete an element from list 5. Quit Enter your choice(1-5) 1 Enter the element: 10 Do you want to enter more elements? (y/n) y Enter the element:20 Do you want to enter more elements?(y/n)y Enter the element:30 Do you want to enter more elements?(y/n)n The List is created Program to perform various operations on Heap using Dynamic memory management. Insert an element in a list 4. Insert an element in a list 4. Quit Enter your choice(1-5) 2 10-> 30-> NULL Heap using Dynamic memory . Quit Enter your choice(1-5) 4 Enter the element you want to delete: 20 The element is present in the list The element is deleted Program to perform various operations on management. Delete an element from list 5. Display 3. 1.

} {identifier}\(if(COMMENT){printf("\n\nFUNCTIONAL\n\t%s". %{ /******************************************************************* Program to obtain tokens from a c program using LEX <lexp.l> *******************************************************************/ int COMMENT = 0.} cnt++. %} identifier[a-zA-Z][a-zA-Z0-9]* %% #.} \{ {if(!COMMENT) printf("\n BLOCK BEGINS"). yytext).} "*/" {COMMENT = 1. Generate Lexical analyzer using LEX.* int | float | char | double | while | for | do | if | break | continue | void | switch | switch | case | long | struct | const | typedef | return | else | goto {printf("\n%is a PREPROCESSOR DIRECTIVE". int cnt = 0.} "*/" {COMMENT = 0.yytext).} .6.} \} {if(!COMMENT)printf("\nBLOCK ENDS").} {printf("\n\t%s is a KEYWORD".yytext).

yytext).} |\n %% int main(int argc. } yylex().print("\n".char**argv) { if(argc>1) { FILE *file'.)? \( = \+| \- {if(!COMMENT)printf("\n\t% is a STRING". } int yywrap() { return 1. return 0.yytext). printf(“ \n Total number of comments are %d”."r").yytext).} {if(!COMMENT)printf("\n\t"). {if(!COMMENT)printf("\n\t%s is an ASSIGNMENT OPERATOR".} \<=| \>=| \<| ==| \> {if(!COMMENT)printf(\n\t%s is a RELATIONAL OPERATOR".)} ECHO.} {if(!COMMENT)printf("\n\t%is a NUMBER".ECHO.cnt). exit(0). if(file) { printf(“\n Could not open %s”. file fopen(argv[1].argv[1].*\" [0-9]+ \)(\.yytext).yytext).yytext)} {if(!COMMENT)printf("\n\t%s is an OPERATOR". } .} \". } yyin = file.{identifier}(\[0-9]*\])? {if(!COMMENT)printf("\n\t%s is an IDENTIFIER".

} else { /* This is a double line comment */ double radius = atof(argv[1]). double area = area_of_circle(radius).area). exit(1).h> #include<stdlib.argv[0]). } . int main(int argc. } return 0.Input File: #include<stdio.radius.h> double area_of_circle(double r). printf(“ Area of circle with radius %f = %f \n”.char *argv[]) { if(argc < 2) { printf(“ Usage: %s radius \n”.

Output: [root@localhost]# lex lexp. exit is an INDENTIFIER (1 is a NUMBER ). int is a KEYWORD main is an INDENTIFIER (int is a KEYWORD argc is an INDENTIFIER char is a KEYWORD argv[] is an INDENTIFIER ) BLOCK if is (argc < is 2 is ) BEGINS a KEYWORD is an INDENTIFIER a RELATIONAL OPERATOR a NUMBER BLOCK BEGINS printf is an INDENTIFIER (“ Usage: %s radius \n”.h> #include<stdlib./a.l [root@localhost]# gcc lex.c [root@localhost]# . BLOCK ENDS else is a KEYWORD BLOCK BEGINS double is a KEYWORD radius is an INDENTIFIER = is an ASSIGNMENT OPERATOR .h> double is a KEYWORD area is an INDENTIFIER of is an INDENTIFIER circle is an INDENTIFIER (double is a KEYWORD r is an INDENTIFIER ).out area.c #include<stdio.yy.is a STRING argv[0] is an INDENTIFIER ).

atof is an INDENTIFIER (argv[1]is an INDENTIFIER ). printf is an INDENTIFIER (“Area of circle with radius %f = %f \n”. is a STRING radius is an INDENTIFIER area is an INDENTIFIER ). double is a KEYWORD area is an INDENTIFIER = is an ASSIGNMENT OPERATOR area is an INDENTIFIER of is an INDENTIFIER circle is an INDENTIFIER (radius is an INDENTIFIER ). BLOCK ENDS return is a KEYWORD 0 is a NUMBER BLOCK ENDS Total number of comments are 3{root@localhost]# .

l %{ /* This LEX program returns the tokens #include “y.h> /* This YYAC program is for recognizing the Expression */ %} %% statement: A’=’E | E { printf(“\n Valid arithmetic expression”).yytext).h” %} %% “=” “+” “-“ “/” “*” for the expression */ {printf(“\n {printf(“\n {printf(“\n {printf(“\n {printf(“\n Operator Operator Operator Operator Operator is is is is is EQUAL”).tab. * and /. return ID.} MULTIPLICATION”).7. \n %% } return yytext[0]. . Program name:arith_id. $$ = $1. int yywrap() { return 1. Generate YACC specification for a few syntactic categories. E: E’+’ID | E’-’ID | E’*’ID | E’/’ID | ID . } Program Name : arith_id.. return 0.} [a-z A-Z]*[0-9]* { printf(“\n Identifier is %s”.y %{ #include<stdio. .} MINUS”). %% extern FILE *yyin.} PLUS”).} DIVISION”). }. a) Program to recognize a valid arithmetic expression that uses operator +.

} return yytext[0]. Program name: variable_test.main() { do { yyparse().c [root@localhost]# ./a.tab.y [root@localhost]# gcc lex. int yywrap() { return 1.tab.1 [root@localhost]# yacc –d arith_id.l %{ /* This LEX program returns the tokens for the Expression */ #include "y.} "double" {return DOUBLE. \n return 0.h" %} %% "int " {return INT. return ID. Identifier is x Operator is EQUAL Identifier is a Operator is PLUS Identifier is b b) Program to recognise a valid variable which starts with a letter followed by any number of letters or digits. } . } yyerror(char*s) { } Output: [root@localhost]# lex arith_id.} "float" {return FLOAT.c y.yy.yytext).out x=a+b.} [a-zA-Z]*[0-9]*{ printf("\nIdentifier is %s". }while(!feof(yyin)).

}while(!feof(yyin)).y [root@localhost]# gcc lex.c [root@localhost]# .out int a. %% extern FILE *yyin./a.y %{ #include <stdio.I [root@localhost]# yacc –d variable_test. Identifier is a Identifier is b[root@localhost]# . L:L.b.h> /* This YACC program is for recognising the Expression*/ %} %token ID INT FLOAT DOUBLE %% D. main() { do { yyparse().yy.Program name: variable_test. } yyerror(char*s) { } Output: [root@localhost]# lex variable_test.tab.T L .ID |ID . T:INT |FLOAT |DOUBLE .c y.

} Program name:anb.} \n return('\n'). %% int yywrap() { return 1.} .} b {return B.c) Program to recognise the gramar(anb where n>=10) Program name: anb.c .1 yacc -d anb.out ./a. anb:A anb |A B .yy. } . yyparse(). } Output: [root@localhost]# [root@localhost]# [root@localhost]# [root@localhost]# lex anb.tab.l %{ /*Lex Program for anb(n>=10)*/ %} %% a {return A. {return yytext[10]. } int yyerror(char*s) { printf("\nInvalid string\n"). %% main() { printf("\nEnter some valid string\n"). return 0.y gcc lex.y %{ /*YACC program for recognising anb(n>=10)*/ %} %token A B %% stmt:A A A A A A A A A A anb'\n'{printf("\n Valid string").c y.

} /*Catch the remaining and return a single character token to the parser*/ return yytext[0].math.[0-9]+)([eE][-+]?[0-9]+)?) {yylval.} /*For ln no (Natural Log)*/ ln {return nLOG. return NUMBER./a.Enter some valid string aaaaaaaaab Invalid string [root@localhost]# .} [\t] .l %{ #include "y.} /*For sin angle*/ sin | SIN {return SINE.h.} /*For log no | Log no (log base 10)*/ log | LOG {return LOG.out Enter some valid string aaaaaaaaaaab Valid string [root@localhost]# d) Implementation of Calculator using LEX and YACC Program name:calci.} /*For tan angle*/ tan | TAN {return TAN.} /*For cos angle*/ cos | COS {return COS. %} %% /*To recognise a valid number*/ ([0-9] + |([0-9]*\.tab.} /*For memory*/ mem {return MEM. /*Ignore white spaces*/ \$ /*End of input*/ {return 0.h" /*defines the tokens*/ #include . \n| %% .dval = atof(yytext).

} /*%prec UMINUS signifies that unary minus should have the highest precedence*/ . } | expression ‘^’ expression {$$ = pow($1. else $$ = $1 / $3.y %{ double memvar.$1).$3. /*For storing the answer(memory)*/ statement: MEM’=’ expression {memvar=$3. %} /*To define possible symbol types*/ %token <dval> NUMBER %token <dval> MEM %token LOG SINE nLOG COS TAN /*Defining the precedences and associativity*/ %left ‘-’ ‘+’ /*Lowest precedence*/ %left ‘*’ ‘/’ %right ‘^’ %left LOG SINE nLOG COS TAN /*Highest precence*/ /*No associativity*/ %nonassoc UMINUS /*Unary Minus*/ /*Sets the type for non-terminal*/ %type <dual> expression %% /*Start state*/ start: statement ‘\n’ | start statement ‘\n’ . /*For printing the Answer*/ /*For binary arithmetic operations*/ expression: expression ‘+’ expression {$$ = $1 + $3.Program Name : calci.} | expression ‘/’ expression { /*Tohandle divide by zero case*/ If($3 == 0) yyerror(“divide by zero”).} | expression ‘*’ expression {$$ = $1 * $3.$3).} .} | expression ‘-’ expression {$$ = $1 .} .} | expression {printf(“Answer = %g\n”. /*For unary operators*/ expression: ‘-’expression %prec UMINUS {$$ = -$2.

} NUMBER {$$ = $1.out Enter the expression: 2+@ Answer = 4 2 * 2 + 5 / 4 Answer = 5.30259 . ‘(’ expression ‘)’ {$$ = $2} LOG expression {$$ = log($2)/log(10).error). } Output: The output of the program can be obtained by following commands [root@localhost]]# lex calci.c lexyy.”%s\n”.} COS expression {$$ = cos($2 * 3.y [root@localhost]]# cc y.141592654 / 180).c –ll –ly –lm [root@localhost]]# .l [root@localhost]]# yacc –d calci. yyparse().141592654 / 180).141592654 / 180).} nLOG expression {$$ = log($2).| | | | | | | | . } int yyerror(char *error) { fprintf(stderr./a.} */Trigonometric functions*/ SINE expression {$$ = sin($2 * 3.} MEM {$$ = $1.25 mem = cos 45 sin 45/mem Answer = 1 ln 10 Answer = 2.} /*Retrieving the memory contents*/ %% main() { printf(“Enter the expression:”).tab.} TAN expression {$$ = tan($2 * 3.

*Out_file. Buffer[i++]=ch. /******************************************************************* Program for Code Optimization Technique of Constant Folding *******************************************************************/ #include<stdio. ReadInput(Bufer. }//End while if(ch ==EOF) break.ch. ch = fgetc(_file). if(ch == EOF) break.char Tokens[][10]).8. }//End main .txt”.”r”). char Buffer[100]. char str[10].FILE *Out_file).txt”. int New_Index=0. In_file = fopen(“d:\\code.h> struct ConstFold ( char new_Str[10]. Buffer[i]=’\0’.//writing to the output file }//End while return 0. clrscr().h> #include<conio. Out_file = fopen(“d:\\output. int i=0. int Gen_token(char str[].”w”). }Opt_Data[20].h> #include<ctype. Given any intermediate code form implement code optimization techniques. void ReadInput(char Buffer[]. i=0.h> #include<string. while(1) { Ch = fgetc(In_file). Out_file).h> #include<stdlib. while(1) { If(ch == ‘\n’) break. int main() { file *In_file.

Token[i-1]).i++) /*Loop to obtain complete tokens*/ { strcat(tem.Buffer). strcpy(temp. while(str[k] ==’ ‘|| str[k] ==’\t’) k++.I.j++) { if(!strcmp(Opt_Data[i].1.new_Str. for(i=0.’||Token[i+1][0] != ‘. while(str[k]!=’\0’) { j=0. strcpy(Opt_Data[New_Index++].Out_file).k=0.Token[i+1]).str).i++) { if(!strcmp(Token[i].Token[i]). strcpy(temp. strcpy(Opt_Data[New_Index]. int n.””). } /*The Gen_Token function breaks the input line into tokens*/ int Gen_Token(char str[]. }//End for strcat(temp.”\n\0”).strlen(temp).FILE *Out_file) { char temp[100]. if(Token[i+1][0]!=’. .Token[10][10].flag=0.i<n.i<n.’) { /*If yes then saving that number and its variable In the Opt_Data array*/ flag=1.i++) { for(j=0.Token). n= Gen_token(temp. fwrite(&temp.i<New_index.j.”=”)) { if(isdigit(Token[i+1][0])||Token[i+1][0] == ’.’) strcat(temp.Opt_Data[i]. char Token[][10]) { int i=0. for(i=0.j=0. }//End for }//End for }//End if fflush(Out_file).New_Str.void ReadInput(char Buffer[].” “).j<n. }//End if }//End if }//End for if(!flag) { for(i=0.Token[j])) strcpy(Token[j].str.

return 0.txt #include<stdio. }//End while return i. }//End if if (str[k] == ‘\0’) break.txt #include<stdio. Token[i++][1] = ‘\0’. a = pi*r*r.14. r.while(str[k])!=’ ’&& str[k]!=’\0’ && str[k]!= ‘=’ && str[k] != ‘/’ && str[k]!= ‘+’ && str[k] != ‘-’ && str[k]!= ‘*’ && str[k] != ‘.h> main() { float pi=3.14 * r * r.r.a). printf(“a = %f”. } Output File: output.h> main() { float pi = 3.’) { Token[i][0] = str[k++]. a = 3. } Input File: code. } .a.a).’) Token[i][j++] = str[k++].’ && str[k]!= ‘.14.’|| str[k] == ‘. if(str[k] == ‘=’|| str[k] == ‘/’|| str[k] == ‘+’|| str[k] == ‘-’|| str[k] == ‘*’|| str[k] == ‘*’|| str[k] == ‘. return 0. printf(“a = %f”. Token[i++][j] = ‘\0’. a.

Write a program to find FIRST of NON TERMINALS of the given grammar.key). } else { key=1.k++) { if(array[i][j]==temp[k]) break. return 0.k<n.int p[].@.int key) { int k. int c. #include"stdio.j.j++) { if(array[i][j-1]=='/') { if(array[i][j]>='A'&&array[i][j]<='Z') { key=0.k++) if(array[i][j]==array[k][0]) break.temp[10]. if(fun2(i. } } void fun(int i. } else { for(k=0. as null symbol.p.p[1]=j+1.9. if(array[i][j]=='@'&&p[0]!=-1) { //taking .int p[]) { int j.p. int fun2(int i.int j.void fun(int.j. fun(k.h> char array[10][20].key)) temp[++c]=array[i][j]. for(j=2.int[]).p).k<=c.h" #include<conio.array[i][j]!='\0'.n. else return 0.key. p[0]=i.k. if(!key) { for(k=0. if(array[p[0]][p[1]]>='A'&&array[p[0]][p[1]]<='Z') { . } if(k>c)return 1. fun2(i.

p[1].j<=c. getch().key)) temp[++c]=array[p[0]][p[1]].p[0]=-1.f ]. fun2(p[0]. for(i=0.@ ]. of productions :6 Enter the productions : S/aBDh B/cC C/bC/@ D/E/F E/g/@ F/f/@ First(S) : [ a ].p).p[1]=-1. } } } } } } void main() { int p[2]. } } Output: Enter the no.array[i][0]).key=0.p[1]. First(D) : [ g. First(F) : [ f.i++) { c=-1.@ ].i.j.\n").temp[j]).&n).p.@. First(C) : [ b. scanf("%d". .@ ]. for(j=0. printf("\b ].i<n. printf("First(%c) : [ ". printf("Enter the productions :\n").i++) scanf("%s". for(i=0. printf("Enter the no.". } else if(array[p[0]][p[1]]!='/'&&array[p[0]][p[1]]!='\0') { if(fun2(p[0]. fun(i.key).p. of productions :").j++) printf("%c. First(E) : [ g. First(B) : [ c ].i<n.array[i]). clrscr().

int p[]) { int j. as null symbol.p.key.p).array[i][j]!='\0'.10. int fun2(int i. p[0]=i.h" #include<conio.key)) temp[t][++c]=array[i][j]. } else { for(k=0.int p[]. else return 0.k<n.j.@. int c.k++) if(array[i][j]==array[k][0]) break.n.int key) { int k. } if(k>c)return 1. fun2(i.h> #define max 10 #define MAX 15 char array[max][MAX]. fun(k. return 0.k.p[1]=j+1.j. if(array[i][j]=='@'&&p[0]!=-1) { //taking .temp[max][MAX].void fun(int.int[]). if(!key) { for(k=0.t. } } void fun(int i. Write a program to find out FOLLOW of NONTERMINALS of given productions.j++) { if(array[i][j-1]=='/') { if(array[i][j]>='A'&&array[i][j]<='Z') { key=0. #include"stdio.key).int j.k++) { if(array[i][j]==temp[t][k]) break. for(j=2. if(array[p[0]][p[1]]>='A'&&array[p[0]][p[1]]<='Z') . } else { key=1. if(fun2(i.k<=c.p.

ff0. } if(null)follow(j).temp[tt][cc]!='\0'.tt++) if(temp[tt][0]==array[j][ii])break. } } } } } } char fol[max][MAX]. fun2(p[0].p[1].j++) if(array[i][0]==ff[j]) return 0.array[j][k]!='\0'.array[j][ii]!='/'&&array[j][ii]!='\0'. } } else fol[l][++f]=array[j][ii].tt<n. else fol[l][++f]=temp[tt][cc]. } .p. for(j=0. void follow(int i) { int j. if(j>ff0)ff[++ff0]=array[i][0]. for(j=0.k++) if(array[j][k]==array[i][0]) ffun(j.k. if(array[j][k+1]=='/'||array[j][k+1]=='\0') null=1.int).j<n.ii++) { if(array[j][ii]<='Z'&&array[j][ii]>='A') { for(tt=0.tt.p[1]. for(ii=k+1. if(i==0)fol[l][++f]='$'.l.j++) for(k=2.cc. void ffun(int. } else if(array[p[0]][p[1]]!='/'&&array[p[0]][p[1]]!='\0') { if(fun2(p[0].int k) { int ii. for(cc=1.p.{ key=0.key)) temp[t][++c]=array[p[0]][p[1]].cc++) { if(temp[tt][cc]=='@')null=1. } void ffun(int j.int f.k).null=0.key).ff[max].j<=ff0.

scanf("%d". First(D) : [ g. fun(i. getch().l++) { f=-1. getch().p[0]=-1.i<n.j++) printf("%c.j. printf("Enter the no.t=0. for(j=1.i. First(C) : [ b. First(B) : [ c ]. .temp[t][j]).i++. temp[t][++c]='\0'.". } for(i=0.j++) printf("%c.p).fol[i][0]).". fol[l][++f]='\0'. fol[l][++f]=array[i][0]. temp[t][0]=array[i][0].temp[t][0]).p[1]=-1. } /* Follow Finding */ for(i=0. printf("\b ].f ]. printf("First(%c) : [ ".@.\n"). for(i=0. } } Output: Enter the no.t++) { c=0.i<n.i++.l=0. of productions :6 Enter the productions : S/aBDh B/cC C/bC/@ D/E/F E/g/@ F/f/@ First(S) : [ a ].j<c. clrscr().ff0=-1. for(j=1.void main() { int p[2]. printf("\b ]").i++) scanf("%s". of productions :").@ ].fol[i][j]!='\0'.array[i]).fol[i][j]).i<n. printf("Enter the productions :\n"). follow(i). for(i=0.i<n.&n).i++) { printf("\nFollow[%c] : [ ".

@ ].h.f. Follow[S] : [ $ ] Follow[B] : [ g. First(F) : [ f.$ ] Follow[C] : [ g.@ ].f.h.First(E) : [ g.$ ] Follow[D] : [ h ] Follow[E] : [ h ] Follow[F] : [ h ] .

Master your semester with Scribd & The New York Times

Special offer for students: Only $4.99/month.

Master your semester with Scribd & The New York Times

Cancel anytime.