0% found this document useful (0 votes)
80 views9 pages

Experiment No 7 - SPCC

The document discusses a YACC experiment to recognize valid arithmetic expressions using operators like +, -, *, and /. It explains the working of YACC, different functions of YACC like grammar specification and parser generation. It also provides an example to define production rules and code for a simple calculator.

Uploaded by

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

Experiment No 7 - SPCC

The document discusses a YACC experiment to recognize valid arithmetic expressions using operators like +, -, *, and /. It explains the working of YACC, different functions of YACC like grammar specification and parser generation. It also provides an example to define production rules and code for a simple calculator.

Uploaded by

Shruti
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 9

Don Bosco Institute of Technology,

Kulra(W)Department of
Computer Engineering
CSL601: System Programming and Compiler Construction Lab2023-
24

Experiment No. 07

Experiment Title
Parser generator tool : Yacc.

Task:

Write a program to recognize valid arithmetic expression


that usesoperators + , -,* and / using YACC.

Student Name

Roll No.

Objectives: To understand parser generator tool : YACC and write


yacc program for recognizing valid arithmetic expression.
Theory /Algorithm:

1) Explain working of YACC Tool and syntax analyzer

2) Explain different functions of yacc tool

3) Explain how to write production rules in yacc specification


withexample
Theory: Yacc, which stands for "Yet Another Compiler Compiler," is a tool
1) Explain working
used in Unix-based systems for generating syntax analyzers or
of YACC Tool
and syntax parsers. Its main purpose is to help in the development of compilers
analyzer
and interpreters by generating the parser component of these
language processors.

Grammar Definition: The first step in using Yacc is to
define the grammar of the language you want to parse.
This grammar is written using a set of rules that describe
the syntax of the language in terms of terminals (tokens)
and non-terminals (symbols).

Yacc File Creation: You create a Yacc source file
(usually with a .y extension) where you define the
grammar rules using a syntax similar to BNF (Backus-
Naur Form). This file includes rules for syntax elements
such as expressions, statements, and other language
constructs.

Tokenization with Lex/Flex: Yacc does not handle the
lexical analysis (tokenization) directly. Typically, you use
a tool like Lex or Flex to generate the lexical analyzer,
which breaks the input text into tokens based on regular
expressions defined in a separate file (usually with a .l
extension).

Integration with Lex/Flex: The output of Lex/Flex (the
token stream) is then integrated with Yacc. Yacc expects
to receive tokens from the lexical analyzer as input.

Parsing Algorithm: Yacc uses a bottom-up parsing
algorithm, specifically LR parsing (Lookahead Left-to-right
Rightmost derivation). This algorithm parses the input text
by constructing a parse tree from the bottom (input symbols)
to the top (start symbol).

Rule Actions: In the Yacc grammar file, you can associate
actions with grammar rules. These actions are snippets of
code (typically in C/C++ syntax) that are executed when the
corresponding rule is matched during parsing. Actions are
where you perform semantic actions such as constructing the
parse tree, evaluating expressions, or generating intermediate
code.

Error Handling: Yacc provides mechanisms for error
handling within the grammar rules. You can define error
rules or use default error handling provided by Yacc to
handle syntax errors gracefully during parsing.

Parser Generation: Once you have defined the grammar,
integrated the lexical analyzer, and specified rule actions, you
run Yacc on the Yacc source file. This generates a parser in
C/ C++ code (usually y.tab.c and y.tab.h files) based on the
grammar rules and actions you defined.

Compilation and Execution: Finally, you compile the
generated parser code along with your lexer (Lex/Flex
output) and any other necessary components of your compiler
or interpreter. The resulting executable can then parse input
programs written in the defined language, construct parse
trees, perform semantic analysis, and generate output (such as
compiled code or interpreted results).

1) Explain different Grammar Specification: Defines the syntax of a
functions of yacc programming language using BNF-like rules.
tool

Parser Generation: Automatically generates a parser
based on the specified grammar.


Bottom-Up Parsing: Utilizes LR parsing for efficient
analysis of context-free grammars.


Symbol Table Management: Supports the creation and
management of symbol tables during parsing.


Action Code Embedding: Allows developers to embed
custom action code within grammar rules.


Error Handling: Provides mechanisms for handling
syntax errors gracefully during parsing.


Integration with Lex/Flex: Works seamlessly with
lexical analyzer generators like Lex/Flex.


Modularity and Reusability: Promotes modularity and
reusability in compiler design by separating parsing
from other compiler phases.


Compiler Construction Support: Essential tool for
building compilers, interpreters, and language
processors.

1) Explain how to Define Terminals and Non-Terminals:
write production • Terminals: These are the basic symbols in the
rules in yacc language, such as identifiers,
specification with keywords, operators, and punctuation.
example • Non-Terminals: These are symbols that
represent groups of terminals and/or other
non-terminals and are used to define the
structure of statements or expressions.

Use Syntax for Production Rules:
• Production rules follow the syntax: non-
terminal : symbols... ;
• The non-terminal is a symbol that appears on
the left-hand side of the rule and represents a
higher-level construct in the language.
• The symbols on the right-hand side can
include terminals (enclosed in quotes) and/or
non-terminals.


Example Production Rules:

%{
#include <stdio.h>
%}

%token NUMBER
%token PLUS MULTIPLY
%left PLUS
%left MULTIPLY

%%
expr : expr PLUS expr { printf("%d + %d\n", $1, $3); $$ =
$1 + $3; }
| expr MULTIPLY expr { printf("%d * %d\n", $1, $3); $$ =
$1 * $3; }
| NUMBER { printf("Number: %d\n", $1); $$ = $1; }
;

%%

int main() {
yyparse();
return 0;
}
In this example:
• %token is used to define terminals (NUMBER,
PLUS, MULTIPLY).
• %left specifies the associativity and precedence of
operators.
• expr is a non-terminal representing an arithmetic
expression.
• The production rules define how expressions are
formed using addition, multiplication, and numbers.
• The action code within curly braces performs
semantic actions like printing and
computation.
• $$ refers to the result of the production rule, and $1,
$3 refer to the symbols on the right-hand side.

Compile and Use:


• Save the Yacc specification in a file (e.g., example.y).
• Compile the Yacc specification using yacc -d
example.y.
• Compile the generated parser and link it with
your program (e.g., gcc -o parser y.tab.c lex.yy.c -
ly -ll).
• Run the compiled parser (./parser) and input
expressions to see the parsing and semantic actions
in action.
Code cal.l
%{
#include "y.tab.h"
#include<math.h>
#include<stdio.h>
%}

%%

[0-9]+ {yylval.num=atof(yytext); return number;}


[-+*/] {return yytext[0];}
COS|cos {return cos1; }
SIN|sin {return sin1; }
TAN|tan {return tan1; }
%%

int yywrap(){
return 1;
}

cal.y
%{
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
int yylex(void);
int yyerror();
%}

%union {double num;}


%start line
%token cos1
%token sin1
%token tan1
%token <num> number
%type <num> exp

%%

line : exp | line exp ;


exp : number {$$=$1;}
| exp '+' number {$$=$1+$3;printf("\n%f+%f=%f\n",
$1,$3,$$);}
| exp '-' number {$$=$1-$3;printf("\n%f-%f=%f\n",$1,$3,$
$);}
| exp '*' number {$$=$1*$3;printf("\n%f*%f=%f\n",
$1,$3,$$);}
| exp '/' number {$$=$1/$3;printf("\n%f/%f=%f\n",$1,$3,$
$);}
| cos1 number {printf("%f",cos(($2/180)*3.14));}
| sin1 number {printf("%f",sin(($2/180)*3.14));}
| tan1 number {printf("%f",tan(($2/180)*3.14));}
;

%%

int main(){
yyparse();
return 0;
}
int yyerror(){
exit(0);
}
Output of
the
program:

Outcome of Utilizing Yacc as a parser generator tool for recognizing


the valid arithmetic expressions involving operators like
addition, subtraction, multiplication, and division can
Experiment:
significantly streamline the process. By defining the
grammar rules and associating actions with these rules,
Yacc enables the creation of a robust parser that can
efficiently parse and validate arithmetic expressions. This
project demonstrates the power and versatility of Yacc in
handling complex parsing tasks, making it a valuable tool
for developers working on language processing and compiler
design projects.
References: • https://www.cs.rochester.edu/u/nelson/courses/csc_173/
grammars/lexyacc_tutorial.html
• https://www.drdobbs.com/cpp/using-yacc-to-parse-
arithmetic-expressio/184401709

Course in-charge-Mayura Gavhane

You might also like