0% found this document useful (0 votes)
13 views10 pages

YACC/C Program for Parsing Techniques

The document discusses the design and implementation of a YACC/C program to demonstrate shift reduce parsing for a grammar. It includes details about the grammar rules, parsing techniques like top-down and bottom-up parsing, shift-reduce parsing and an example C program to parse an expression using shift-reduce parsing.

Uploaded by

Unicorn
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
13 views10 pages

YACC/C Program for Parsing Techniques

The document discusses the design and implementation of a YACC/C program to demonstrate shift reduce parsing for a grammar. It includes details about the grammar rules, parsing techniques like top-down and bottom-up parsing, shift-reduce parsing and an example C program to parse an expression using shift-reduce parsing.

Uploaded by

Unicorn
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

System Software and Operating System Laboratory[18CSL66]

3. Design, develop and implement YACC/C program to construct Predictive / LL(1) Parsing Table
for the grammar rules: A →aBa , B →bB | ε. Use this table to parse the sentence: abba$.
#include<stdio.h>
#include<conio.h>
#include<string.h>
void main()
{
char fin[10][20],st[10][20],ft[20][20],fol[20][20];
int a=0,e,i,t,b,c,n,k,l=0,j,s,m,p;
printf("enter the no. of coordinates\n");
scanf("%d",&n);
printf("enter the productions in a grammar\n");
for(i=0;i<n;i++)
scanf("%s",st[i]);
for(i=0;i<n;i++)
fol[i][0]='\0';
for(s=0;s<n;s++)
{
for(i=0;i<n;i++)
{
j=3;
l=0;
a=0;
l1:if(!((st[i][j]>64)&&(st[i][j]<91)))
{
for(m=0;m<l;m++)
{
if(ft[i][m]==st[i][j])
goto s1;
}
ft[i][l]=st[i][j];
l=l+1;
s1:j=j+1;
}
else
{
if(s>0)
{
while(st[i][j]!=st[a][0])
{
a++;
}
b=0;

Dept. of CSE, GSSSIETW, Mysuru Page 15


System Software and Operating System Laboratory[18CSL66]

while(ft[a][b]!='\0')
{
for(m=0;m<l;m++)
{
if(ft[i][m]==ft[a][b])
goto s2;
}
ft[i][l]=ft[a][b];
l=l+1;
s2:b=b+1;
}
}
}
while(st[i][j]!='\0')
{
if(st[i][j]=='|')
{
j=j+1;
goto l1;
}
j=j+1;
}
ft[i][l]='\0';
}
}
printf("first pos\n");
for(i=0;i<n;i++)
printf("FIRS[%c]=%s\n",st[i][0],ft[i]);
fol[0][0]='$';
for(i=0;i<n;i++)
{
k=0;
j=3;
if(i==0)
l=1;
else
l=0;
k1:while((st[i][0]!=st[k][j])&&(k<n))
{
if(st[k][j]=='\0')
{
k++;
j=2;

Dept. of CSE, GSSSIETW, Mysuru Page 16


System Software and Operating System Laboratory[18CSL66]

}
j++;
}
j=j+1;
if(st[i][0]==st[k][j-1])
{
if((st[k][j]!='|')&&(st[k][j]!='\0'))
{
a=0;
if(!((st[k][j]>64)&&(st[k][j]<91)))
{
for(m=0;m<l;m++)
{
if(fol[i][m]==st[k][j])
goto q3;
}
q3:
fol[i][l]=st[k][j];
l++;

}
else
{
while(st[k][j]!=st[a][0])
{
a++;
}
p=0;
while(ft[a][p]!='\0')

{
if(ft[a][p]!='@')
{
for(m=0;m<l;m++)
{
if(fol[i][m]==ft[a][p])
goto q2;
}
fol[i][l]=ft[a][p];
l=l+1;
}
else
e=1;
q2:p++;

Dept. of CSE, GSSSIETW, Mysuru Page 17


System Software and Operating System Laboratory[18CSL66]

}
if(e==1)
{
e=0;
goto a1;
}
}
}
else
{
a1:c=0;
a=0;
while(st[k][0]!=st[a][0])
{
a++;

}
while((fol[a][c]!='\0')&&(st[a][0]!=st[i][0]))
{
for(m=0;m<l;m++)
{
if(fol[i][m]==fol[a][c])
goto q1;
}
fol[i][l]=fol[a][c];
l++;
q1:c++;
}
}
goto k1;
}
fol[i][l]='\0';
}
printf("follow pos\n");
for(i=0;i<n;i++)
printf("FOLLOW[%c]=%s\n",st[i][0],fol[i]);
printf("\n");
s=0;
for(i=0;i<n;i++)
{
j=3;
while(st[i][j]!='\0')
{
if((st[i][j-1]=='|')||(j==3))

Dept. of CSE, GSSSIETW, Mysuru Page 18


System Software and Operating System Laboratory[18CSL66]

{
for(p=0;p<=2;p++)
{
fin[s][p]=st[i][p];
}
t=j;
for(p=3;((st[i][j]!='|')&&(st[i][j]!='\0'));p++)
{
fin[s][p]=st[i][j];
j++;
}
fin[s][p]='\0';
if(st[i][t]=='@')
{
b=0;
a=0;
while(st[a][0]!=st[i][0])
{
a++;
}
while(fol[a][b]!='\0')
{
printf("M[%c,%c]=%s\n",st[i][0],fol[a][b],fin[s]);
b++;
}
}
else if(!((st[i][t]>64)&&(st[i][t]<91)))
printf("M[%c,%c]=%s\n",st[i][0],st[i][t],fin[s]);
else
{
b=0;

a=0;
while(st[a][0]!=st[i][3])
{
a++;
}
while(ft[a][b]!='\0')
{
printf("M[%c,%c]=%s\n",st[i][0],ft[a][b],fin[s]);
b++;
}
}
s++;

Dept. of CSE, GSSSIETW, Mysuru Page 19


System Software and Operating System Laboratory[18CSL66]

}
if(st[i][j]=='|')
j++;
}
}
getch();
}
Output:

Dept. of CSE, GSSSIETW, Mysuru Page 20


System Software and Operating System Laboratory[18CSL66]

4. Design, develop and implement YACC/C program to demonstrate Shift Reduce Parsing technique for
the grammar rules: E →E+T | T, T →T*F | F, F → (E) | id and parse the sentence: id + id * id.
A parser is a compiler or interpreter component that breaks data into smaller elements for easy
translation into another language. A parser takes input in the form of a sequence of tokens or program
instructions and usually builds a data structure in the form of a parse tree or an abstract syntax tree.
A parser's main purpose is to determine if input data may be derived from the start symbol of the
grammar.
Syntax analyzers follow production rules defined by means of context-free grammar. The way the
production rules are implemented (derivation) divides parsing into two types: top-down parsing and
bottom-up parsing.

Top-down Parsing
When the parser starts constructing the parse tree from the start symbol and then tries to transform the
start symbol to the input, it is called top-down parsing.
 Recursive descent parsing: It is a common form of top-down parsing. It is called recursive as it uses
recursive procedures to process the input. Recursive descent parsing suffers from backtracking.
 Backtracking: It means, if one derivation of a production fails, the syntax analyzer restarts the process
using different rules of same production. This technique may process the input string more than once to
determine the right production.

Dept. of CSE, GSSSIETW, Mysuru Page 21


System Software and Operating System Laboratory[18CSL66]

Bottom-up Parsing
Bottom-up parsing starts with the input symbols and tries to construct the parse tree up to the start
symbol.
Shift-reduce Parsing (Bottom-up Parsing)
Shift-reduce parsing attempts to construct a parse tree for an input string beginning at the leaves and
working up towards the root. In other words, it is a process of “reducing” (opposite of deriving a symbol
using a production rule) a string w to the start symbol of a grammar. At every (reduction) step, a
particular substring matching the RHS of a production rule is replaced by the symbol on the LHS of the
production.
A general form of shift-reduce parsing is LR (scanning from Left to right and using Right-most
derivation in reverse) parsing, which is used in a number of automatic parser generators like Yacc,
Bison, etc.
#include<stdio.h>
#include<conio.h>
#include<string.h>
int k=0,z=0,i=0,j=0,c=0;
char a[16],ac[20],stk[15],act[10];
void check();
void main()
{
puts("GRAMMAR is E->E+E \n E->E*E \n E->(E) \n E->id");
puts("enter input string ");
gets(a);
c=strlen(a);
strcpy(act,"SHIFT->");
puts("stack \t input \t action");
for(k=0,i=0; j<c; k++,i++,j++)
{
if(a[j]=='i' && a[j+1]=='d')
{
stk[i]=a[j];
stk[i+1]=a[j+1];
stk[i+2]='\0';
a[j]=' ';
a[j+1]=' ';
printf("\n$%s\t%s$\t%sid",stk,a,act);
check();
}
else

Dept. of CSE, GSSSIETW, Mysuru Page 22


System Software and Operating System Laboratory[18CSL66]

{
stk[i]=a[j];
stk[i+1]='\0';
a[j]=' ';
printf("\n$%s\t%s$\t%ssymbols",stk,a,act);
check();
}
}
getch();
}
void check()
{
strcpy(ac,"REDUCE TO E");
for(z=0; z<c; z++)
if(stk[z]=='i' && stk[z+1]=='d')
{
stk[z]='E';
stk[z+1]='\0';
printf("\n$%s\t%s$\t%s",stk,a,ac);
j++;
}
for(z=0; z<c; z++)
if(stk[z]=='E' && stk[z+1]=='+' && stk[z+2]=='E')
{
stk[z]='E';
stk[z+1]='\0';
stk[z+2]='\0';
printf("\n$%s\t%s$\t%s",stk,a,ac);
i=i-2;
}
for(z=0; z<c; z++)
if(stk[z]=='E' && stk[z+1]=='*' && stk[z+2]=='E')
{
stk[z]='E';
stk[z+1]='\0';
stk[z+1]='\0';
printf("\n$%s\t%s$\t%s",stk,a,ac);
i=i-2;
}
for(z=0; z<c; z++)
if(stk[z]=='(' && stk[z+1]=='E' && stk[z+2]==')')
{
stk[z]='E';
stk[z+1]='\0';
stk[z+1]='\0';

Dept. of CSE, GSSSIETW, Mysuru Page 23


System Software and Operating System Laboratory[18CSL66]

printf("\n$%s\t%s$\t%s",stk,a,ac);
i=i-2;
}
}
Output:

Dept. of CSE, GSSSIETW, Mysuru Page 24

Common questions

Powered by AI

The primary goal of a parser in context-free grammar is to determine if input data can be derived from the start symbol of the grammar. This is achieved by constructing a parse tree or an abstract syntax tree that represents the hierarchical structure of the input, following the production rules defined by the grammar .

Shift-reduce parsing handles conflicts primarily through precedence and associativity rules or by using more sophisticated parsing algorithms like LR parsers. Common conflicts include 'shift/reduce' conflicts, where the parser must choose between shifting a symbol onto the stack or reducing a sequence, and 'reduce/reduce' conflicts, where multiple production rules can reduce the same input, which can often be resolved by parser-predefined precedence .

Recursive descent parsing faces challenges due to backtracking, as it may require the parser to repeatedly attempt different production rules until a match is found. This can lead to inefficiencies, as the same input may need to be processed multiple times, increasing the computational overhead and potentially leading to exponential time complexity in parsing ambiguous or complex grammars .

In shift-reduce parsing, the stack plays a vital role by holding symbols that have been processed and are candidates for reduction. Symbols are 'shifted' onto the stack from the input, and when a sequence of stack symbols matches the RHS of a production, they are 'reduced' to the LHS symbol. This process moves the derivation of the input closer to the start symbol, thus constructing the parse tree and guiding the parsing process .

A parsing table aids in parsing sentences like 'abba$' by mapping each combination of stack top and input symbol to a specific production rule. Using LL(1) parsing, each step examines the current input and the top stack symbol, referring to the table to predict the correct production, ensuring efficient and correct parsing without backtracking. For 'abba$', the parsing table guides the derivation from the start symbol to match the input .

In shift-reduce parsing, reduction is the process of replacing a substring of the input that matches the right-hand side (RHS) of a production rule with the left-hand side (LHS) non-terminal. This action effectively combines individual tokens into larger syntactic constructs, moving up the parse tree hierarchy towards the start symbol, and progressively constructing the parse tree from leaves to root .

Context-free grammars form the foundation for parsers in syntax analyzers as they provide a formal structure for specifying language syntax rules. Parsers use these production rules to validate the grammatical structure of input, constructing parse trees or abstract syntax trees that represent the hierarchical and nested relationships defined by the grammar .

Recursive descent parsing is a form of top-down parsing that starts constructing parse trees from the start symbol and transforms it to the input recursively, often suffering from backtracking. In contrast, shift-reduce parsing is a bottom-up approach that begins with the input symbols, constructing the parse tree from the leaves upwards to the start symbol. It works by 'shifting' input symbols onto a stack and 'reducing' sequences that match the RHS of a production with the LHS symbol .

The LL(1) parsing table ensures syntactical correctness by using the 'lookahead' feature, where the next input symbol is used to correctly choose the production rule based on both the input and the stack's current state. This limits parsing decisions to one production per situation, preventing ambiguities and mismatches, thus enforcing the grammatical structure of the input .

A predictive or LL(1) parsing table facilitates parsing by providing a precomputed decision structure that dictates which production rules to apply based on the current input symbol and the top of the stack. This eliminates backtracking and allows for efficient top-down parsing by predicting the correct production to use at each step .

You might also like