Professional Documents
Culture Documents
BCSE307L 21BAI1743 Compiler Lab4
BCSE307L 21BAI1743 Compiler Lab4
Prepared by:
Slot: L15+L16
LAB -4
ALGORITHM:
1. Lexer (calculator.l):
- Include the required header files and declare the yylval variable.
- Define token patterns and their corresponding actions using regular expressions.
- Convert recognized numbers to integers and assign them to yylval.
- Return the appropriate tokens for operators and other characters. - Handle special characters like tabs
and newlines.
2. Parser (calculator.y):
- Include the necessary header files and define variables.
- Declare the tokens using the %token directive.
- Specify the operator precedence using %left directives.
- Define grammar rules for arithmetic expressions using BNF notation.
- Calculate the result and print it in the ArithmeticExpression rule.
- Handle different operators and parentheses by recursively evaluating expressions.
- Assign the value of numbers to $$ (the result).
3. Main Function:
- Prompt the user to enter an arithmetic expression.
- Invoke the parser using yyparse() to evaluate the expression.
- Print the result if the expression is valid.
- Display an error message if the expression is invalid.
4. Error Handling:
- Implement the yyerror() function to handle parsing errors.
- Set a flag variable to indicate an invalid expression.
- Terminate the program.
CODE :
// Calculator.l
%{
#include <stdio.h>
#include <stdlib.h>
#include "y.tab.h"
extern int yylval;
%}
%%
[0-9]+ {
yylval = atoi(yytext);
return NUMBER;
}
[\t] ;
[\n] return 0;
. return yytext[0];
%%
int yywrap()
{
return 1;
}
// Calculator.y
%{
#include <stdio.h>
int flag = 0;
%}
%token NUMBER
%left '+' '-'
%left '*' '/' '%'
%left '(' ')'
%%
ArithmeticExpression:
E{
printf("\nResult = %d\n", $$);
return 0;
};
E:
E '+' E { $$ = $1 + $3; }
| E '-' E { $$ = $1 - $3; }
| E '*' E { $$ = $1 * $3; }
| E '/' E { $$ = $1 / $3; }
| E '%' E { $$ = $1 % $3; }
| '(' E ')' { $$ = $2; }
| NUMBER { $$ = $1; }
;
%%
int main(void)
{
printf("\nEnter Arithmetic Expression:\n");
yyparse();
if (flag == 0)
printf("\nEntered arithmetic expression is valid\n\n");
return 0;
}
void yyerror(const char *s)
{
printf("\nEntered arithmetic expression is invalid\n\n");
flag = 1;
}
Input :
The input for this program would be stored in a linear array. Here the input is :
For Addition the following input is given:
“4+5”
For Subtraction the following input is given:
“5-4”
For Multiplication the following input is given:
“4*5”
For Division the following input is given:
“5/4”
Constraint:
The Arithmetic Expression must have operations like Addition, Subtraction, Multiplication,
Division, Modulus and Round brackets only.
Output :
Conclusion :
By leveraging LEX for token recognition and YACC for grammar rules and evaluation, the code achieves
accurate parsing and evaluation of expressions involving basic operators.
AIM:
Implementation of Abstract syntax tree –Infix to postfix using the LEX and YACC tools.
Algorithm :
- Define the lexer rules in the `infix_to_postfix.l` file to tokenize the input expression into
identifiers
(IDs) and operators.
- Utilize the Lex tool to implement the lexer and generate the lexer code (`lex.yy.c`).
- Define the Yacc rules in the `infix_to_postfix.y` file to specify the grammar for the infix
expression
and postfix conversion.
- Use the Yacc tool to implement the parser and generate the parser code (`y.tab.c`).
- Define the necessary data structures, such as the node structure, to represent the expression
tree.
- Implement the functions `mkleaf` and `mknode` to create leaf nodes and operator nodes in
the
expression tree.
- Implement the `display` function to print the preorder traversal of the expression tree.
- Implement the `convertToPostfix` function to convert the infix expression to postfix notation
by
traversing the expression tree in postorder.
- Implement the `yyerror` function to handle parsing errors and display error messages.
- In the `main` function, call `yyparse` to initiate the parsing process.
- Inside the `stmt` rule, call `convertToPostfix` to convert the infix expression to postfix and
display
the result.
- Terminate the program.
These steps outline the process of creating a lexer and parser using Lex and Yacc to convert an
infix
expression to postfix notation, building an expression tree, and performing various operations
on it.
Code :
// Lex
%{
#include "y.tab.h"
extern int yylval;
void yyerror(char *error);
%}
L [a-zA-Z]
%%
{L} { yylval = (int)yytext[0]; return ID; }
. { return *yytext; }
[\t];
[\n] return 0;
%%
int yywrap() {
return 1;
}
// YACC
%{
#include <stdio.h>
#include <stdlib.h>
extern int yylex();
extern int yyparse();
typedef union {
int intval;
char charval;
} type;
typedef struct node {
type data;
struct node* lptr, * rptr;
} node;
node* mknode(char dt, node* ln, node* rn);
node* mkleaf(char dt, node* ln, node* rn);
void display(node* root);
void convertToPostfix(node* root);
int op;
%}
%union {
int intval;
char charval;
struct node* nptr;
}
%token <intval> NUM
%token <charval> ID
%type <nptr> exp
%type <nptr> postfix
%left '*' '/'
%left '+' '-'
%right '^'
%start stmt
%%
stmt: exp {
printf("\nPostfix Expression: ");
convertToPostfix($1);
printf("\n");
}
exp: ID {
$$ = mkleaf($1, NULL, NULL);
}
| exp '=' exp {
$$ = mknode('=', $1, $3);
}
| exp '+' exp {
$$ = mknode('+', $1, $3);
}
| exp '-' exp {
$$ = mknode('-', $1, $3);
}
| exp '*' exp {
$$ = mknode('*', $1, $3);
}
| exp '/' exp {
$$ = mknode('/', $1, $3);
}
postfix: exp {
$$ = $1;
}
%%
node* mkleaf(char dt, node* ln, node* rn) {
node* temp = (node*)malloc(sizeof(node));
temp->data.charval = dt;
temp->lptr = ln;
temp->rptr = rn;
return temp;
}
node* mknode(char dt, node* ln, node* rn) {
node* temp = (node*)malloc(sizeof(node));
temp->data.charval = dt;
temp->lptr = ln;
temp->rptr = rn;
return temp;
}
void display(node* root) {
if (root != NULL) {
if (root->lptr == NULL && root->rptr == NULL) {
printf("%c", root->data.charval);
}
else {
printf("%c", root->data.charval);
}
display(root->lptr);
display(root->rptr);
}
}
void convertToPostfix(node* root) {
if (root != NULL) {
convertToPostfix(root->lptr);
convertToPostfix(root->rptr);
printf("%c", root->data.charval);
}
}
void yyerror(char* error) {
printf("\n%s", error);
}
int main() {
yyparse();
return 0;
}
Input:
Here, the given input is a+b*c which is the infix expression
Output:
The program will covert infix expression to postfix
Conclusion:
In summary, the code effectively utilizes the LEX and YACC tools to build an Abstract Syntax Tree
(AST) for converting infix expressions to postfix notation. The lexer (infix_to_postfix.l) is responsible for
tokenizing the input expression, while the parser (infix_to_postfix.y) defines the grammar rules and
constructs the AST. The AST enables efficient conversion of infix expressions to postfix notation,
facilitating further processing or evaluation of the expressions