YACC in Compiler Design

YACC 

YACC is known as Yet Another Compiler Compiler. It is used to produce the source code of the syntactic analyzer of the language produced by LALR (1) grammar. The input of YACC is the rule or grammar, and the output is a C program. Stephen C. Johnson creates the first kind of YACC. If we have a file translate.y that consists of YACC specification, then the UNIX system command is:

YACC translate.y

This command converts the file translate.y into a C file y.tab.c. It represents an LALR parser prepared in C with some other user’s prepared C routines. By compiling y.tab.c along with the ly library, we will get the desired object program a.out that performs the operation defined by the original YACC program.

The construction of translation using YACC is illustrated in the figure below:

A YACC source program contains three parts:

  • Declarations

%%

  • Translation rules

%%

  • Supporting C rules

Declarations Part

This part of YACC has two sections; both are optional. The first section has ordinary C declarations, which is delimited by %{ and %}. Any temporary variable used by the second and third sections will be kept in this part. See the below code:

%{

#include <ctype.h>

%}

%token DIGIT

%%

line               :  expr  ‘\n’                { printf("%d\n", $1); }

                     ;

expr              :  expr   '+' term          { $$ = $1 + $3; }

                     |   term

                     ;

term              :  term '*' factor           { $$ = $1 * $3; }

                     |  factor

                     ;

factor            :  ‘(‘ expr ’)’                  { $$ = $2; }

                     |    DIGIT

                     ;

%%

yylex() {

int c;

c = getchar();

if (isdigit(c)) {

yylval = c-'0';

return DIGIT;

}

return c;

}

In the above code, the declaration part only contains the include statement.

#include <ctype.h>

Declaration of grammar tokens also comes in the declaration part.

%token DIGIT

This part defined the tokens that can be used in the later parts of a YACC specification. 

Translation Rule Part

After the first %% pair in the YACC specification part, we place the translation rules. Every rule has a grammar production and the associated semantic action.

A set of productions:

                         <head> => <body>1 | <body>2 | ..... | <body>n

would be written in YACC as

                            <head>    :      <body>1          {<semantic action>1}

                                            |      <body>2          {<semantic action>2}

                                                     .....

                                             |       <body>n         {<semantic action>n}

                                             ;

In a YACC production, an unquoted string of letters and digits that are not considered tokens is treated as non-terminals.

The semantic action of YACC is a set of C statements. In a semantic action, the symbol $$ considered to be an attribute value associated with the head's non-terminal. While $i considered as the value associated with the ith grammar production of the body.

If we have left only with associated production, the semantic action will be performed. The value of $$ is computed in terms of $i's by semantic action.

Supporting C–Rules

It is the last part of the YACC specification and should provide a lexical analyzer named yylex(). These produced tokens have the token's name and are associated with its attribute value. Whenever any token like DIGIT is returned, the returned token name should have been declared in the first part of the YACC specification.

The attribute value which is associated with a token will communicate to the parser through a variable called yylval. This variable is defined by a YACC.

Whenever YACC reports that there is a conflict in parsing-action, we should have to create and consult the file y.output to see why this conflict in the parsing-action has arisen and to see whether the conflict has been resolved smoothly or not.

Instructed YACC can reduce all parsing action conflict with the help of two rules that are mentioned below:

  • A reduce/reduce conflict can be removed by choosing the production which has conflict mentioned earlier in the YACC specification.
  • A shift/reduce conflict is reduced in favor of shift. A shift/reduce conflict that arises from the dangling-else ambiguity can be solved correctly using this rule.

Related Topics

CLR Parsing Compiler Design

CLR Parsing CLR parsing refers to the canonical lookahead. We will use the canonical collection of LR(1) items for the construction of the CLR(1) parsing table. Generally, CLR(1) parsing has more...

6 minutes read.

Storage Allocation

Storage Allocation The storage allocation represents memory management. The allocation of memory can be done in the following ways: Static AllocationStack AllocationHeap Management Static Allocation: It is a procedure used for the allocation of...

1 minute read.

Regular Expression | Compiler Design

Regular Expression A regular expression is a set of patterns that can match a character or string. It can also match alternative characters or strings. The grammar defined by the regular...

3 minutes read.

Bottom-Up Parsing in Compiler Design

Bottom-Up Parsing A bottom-up parsing constructs the parse tree for an input string beginning from the bottom (the leaves) and moves to work towards the top (the root). Bottom-up parsing is...

6 minutes read.

Intermediate-Code Generator Compiler Design

Intermediate-Code Generator The process of translating a source language into machine code for a given target machine is done by intermediate-code. It lies between the high-level language and the machine language....

2 minutes read.

S-attributed and L-attributed SDTs

S-attributed and L-attributed SDTs STD stands for Syntax Directed Translation. When we associate some informal notations called semantic rules and the grammar, they are known as STD. So we can say...

2 minutes read.

LALR 1 Parsing | Compiler Design

LALR (1) Parsing The LALR parsing refers to the "lookahead LR" that has many lesser steps than typical parsers based on LR(1) items. For constructing the LALR(1) parsing table, the canonical...

6 minutes read.

Syntax-Directed Translation

Syntax-Directed Translation A context-free-grammar with some additional rules is known as a syntax-directed definition. In SDT, attributes are associated with grammar symbols and rules are associated with productions. The attributes can...

3 minutes read.

Compiler Design Tutorial

Our compiler design tutorial will provide all the information about compiler from basic to advanced level. This compiler tutorial will help the student for their semester as well as for...

3 minutes read.

Run-Time Storage Management

Run-Time Storage Management Every executing program has its own logical address space. Logical address space is partitioned into: Code: It is responsible for storing the executable target code. Static: It is used to...

3 minutes read.

Stack Allocation of Space

Stack Allocation of Space Almost all compilers for languages that use procedure, functions, or methods manage their run-time memory as a stack. Whenever a procedure is called, the local variable's space...

2 minutes read.

Data Flow Analysis in Compiler Design

Data Flow Analysis All the optimization techniques we have learned earlier depend on data flow analysis. DFA is a technique used to know about how the data is flowing in any...

3 minutes read.

Shift Reduce Parsing in Compiler Design

Like the bottom-up parsing, the shift reduce parser also builds the parse tree from the leaves (bottom) to the root (up). The LR parser is a more versatile variation of...

4 minutes read.

Symbol Table Compiler Design

Symbol Table It is an important data structure used by the compiler. It stores information about various entities such as object, class, variable names, functions name, interfaces, procedure, literals, string etc.  The...

3 minutes read.

Target Machine

Target Machine A target machine is a byte-addressable machine. This machine has n general-purpose registers, R0, R1,.....Rn-1. A Simple Target Machine Model has three-address instruction. A full-edged assembly language would have...

3 minutes read.

Three-Address Code

Three-Address Code If there is at most one operator on the right side of the instruction, then the instruction will be the three-address code so that no arithmetic expressions are permitted....

2 minutes read.

Errors in Compiler Design

Introduction Errors in compiler design refer to mistakes or issues that arise during the process of execution of the program. A compiler is a program that translates source code written in...

4 minutes read.

Switch Case Statement Compiler Design

Case Statement The “case” or “switch” statement is available in various languages. The following is the syntax for the case statement: switch (E)  {             case V1: S1             case V2: S2 ...

1 minute read.

Boolean Expression in Compiler Design

Boolean Expression The translation of conditional statements such as if-else statements and while-do statements is associated with Boolean expression's translation. The main use of the Boolean expression is the following: Boolean expressions...

3 minutes read.

Finite State Machine

Finite State Machine A finite state machine is a simple machine to recognize patterns. It takes a string of symbols as the input and changes its state to another state, but...

3 minutes read.