Menu

[Solved]Goal Exercise Acquaint Two Powerful Tools Generation Compilers Flex Bison Homework Files Q37190247

The goal of this exercise is to acquaint yourself with two verypowerful tools for the generation of compilers: ​flex and ​bison​.In this homework files for a calculator application are provided toyou. The files are as the following list.

File

Description

calc.l

Contains the regular expression rules

calc.y

Contains the grammar rules

calc.h

Contains a data structure used by calculator

mymake

Contains the make commands to build the application

You need to transfer the files to a directory in your glaccount. The address of gl account is gl.umbc.edu. You need to usea FTP application to transfer the files.

The following command builds the calculator application:

[user@linux2] make -f mymake calc

After building the application you can run the executable file​calc which is created in the folder. The following examplepresents a session of running the calculator. At the prompt ofcalculator user can enter any arithmetic expression and by pressingenter the calculator evaluates the arithmetic expression. The exitcommand is dot, and by typing ? character user can get helpinstructions on the calculator prompt.

[user@linux2] calc >> 3 + 4
7
>> .

[user@linux2]

Your job is to modify the application to add logical operatorsas in the following table. All operators will have leftassociativity.

1

Operator

Meaning

Precedence

Description

&

Logical and

Lowest

This is equivalent to && in C language. It is a binaryoperator. If it evaluates to true, it returns 1 and if evaluates tofalse it returns 0.

|

Logical or

Same as &

This is equivalent to || in C language. It is a binary operator.If it evaluates to true, it returns 1 and if evaluates to false itreturns 0.

==

Equal

Higher than & and |, lower than >

It is a binary operator. If both sides are of equal values, itreturns 1, otherwise it returns 0.

>

Greater than

Highest

It is a binary operator. If left operand has a greater valuethan right operand, it returns 1, otherwise it returns 0.

The following is an example test session that your applicationcan be tested against. You need to test your modifications for allfour operators you have added.

>> a = 5 >> b = 8 >> a > b 0

You need to submit your modified files, i.e. ​calc.l and ​calc.ythrough the submit utility on your gl account.

Hints:

  • ● In this application you do not need to modify the grammarrules to implement associativity and precedence of operators. Theycan be defined for ​bison​, andbison​ will implement them.

  • ● In the declaration section of ​calc.y you can define theprecedence and associativity of operators. The precedence andassociativity of arithmetic operators are already defined in thisfile. You can define this information for your logical operators inthe same place and in the same way.

  • ● Logical and (&) has a higher precedence than assignment(=) operator, and Greater than (>) has a lower precedence than +and – operators

CALC.H

/* SYMBOLTABLESIZE is the maximum number of sysbols we can have */#define SYMBOLTABLESIZE 20/* An entry in the symbol table has a name, a pointer to a function, and a numeric value. */struct symtab { char *name; double (*funcptr)(); double value;} symtab[SYMBOLTABLESIZE];struct symtab *symlook();void printHelp();void yyerror();

CALC.Y

%{

#include “calc.h”

#include <string.h>

#include <math.h>

#include <stdio.h>

#include <stdlib.h>

/************************************************************************

* Defines a yacc grammar for a simple calculator using infix

* notation. WHen executed, the calculator enters a loop in

* which it prints the prompt >>, reads a toplevelexpression

* terminated by a newline, and prints its value. Operators

* include +, -, *, and = (assignment). Note that all

* expressions return values, even assignment. Parentheses

* can be used to override operator precedence and

* associativity rules. Based on zcalc by ruiz@capsl.udel.edu

************************************************************************/

int yylex();

int yyparse();

%}

/*

Th union directive specifies the collection of tpes ourgrammar

deals with — just doubles and pointers to symbol tableentries.

*/

%union {

double dval;

struct symtab *symp;

}

/*

Declare the token types and any associated value types. Wemade

EQ a token in calc.l because otherwise ‘=’ and ‘==’ wouldclash.

*/

%token <symp> NAME

%token <dval> NUMBER

/* The folowing declarations specify the precidence andassociativity

   of our operators. The operators -, +, * and / to beleft

   associative, * and EQ to be right associative andUMINUS to be

   non-associative (since it is a unary operator). The’=’ operator

   has the lowest precedence and UMINUS thehighest.

*/

%right ‘=’ /*lowest precedence*/

%left ‘-‘ ‘+’

%left ‘*’ ‘/’

%nonassoc UMINUS /* highest precedence */

/*

Declare the type of expression to be a dval (double).

*/

%type <dval> expr

%%

/*

Here are our grammar rules. a session is a sequence of lines.A

toplevel is just an expr (print its value followed by two

newlines and the prompt >>) or a ‘? (print help) or a ‘.'(exit).

An expr can be a number, name, the sum of two exprs, …

*/

session: /* empty */

   |

session toplevel ‘n’

;

toplevel: expr { printf(“%gnn>> “, $1); }

| ‘?’ { printHelp(); printf(“n>> “); }

| ‘.’ { printf(“Exiting 331 calcn”); exit(1); }

;

expr: NUMBER { $$ = $1; }

   | NAME { $$ = $1->value; }

   | NAME ‘=’ expr { $1->value = $3; $$ = $3; }

   | expr ‘+’ expr { $$ = $1 + $3; }

   | expr ‘-‘ expr { $$ = $1 – $3; }

   | expr ‘*’ expr { $$ = $1 * $3; }

   | expr ‘/’ expr { $$ = $1 / $3; }

   | ‘-‘ expr %prec UMINUS { $$ = -$2; }

   | ‘(‘ expr ‘)’ { $$ = $2; }

;

%%

struct symtab *

symlook(s)

char *s;

{

   char *p;

   struct symtab *sp;

   /* given the name of a symbol, scan the symboltable and

either return the entry with matching name or add it

to the next free cell in the symbol table. */

   for(sp = symtab; sp <&symtab[SYMBOLTABLESIZE]; sp++) {

   /* If the symbol table entry has a name and itsequal

to the one we are looking for, return this entry */

   if (sp->name && !strcmp(sp->name,s))

   return sp;

   /* If the name is empty then this entry is free, sothe

symbol must not be in the table and we can add it here

and return this entry. */

   if (!sp->name) {

   sp->name = strdup(s);

   return sp;

   }

   }

   /* We searched the entire symbol table and neitherfound

the symbol or an unused entry. So the table must be

full. Sigh. */

   yyerror(“The symbol table is full,sorry…n”);

   exit(1);

}

void printHelp()

{ /* print calculator help and return */

printf(“Enter an expression in infix notation followed by anewline.n”);

printf(“Operators include +, -, * and =. Defined functionsincluden”);

printf(“sqrt, exp and log. You can assign a variable using the=n”);

printf(“operator. Type . to exit. Syntax errors will terminatethen”);

printf(“program, so be careful.n”);

}

/* If error prints error and Do not accept to signify bad syntaxin

   program */

void yyerror(char *msg) /* yacc error function */

{

printf(“%s n” , msg);

}

int yywrap(){return 1;}

int main()

{ /* print herald and call parser */

printf(“331 Calculatorn(type ? for help and . toexit)nn>> “);

yyparse();

return 0;

}

CALC.L

%{

#include “y.tab.h”

#include “calc.h”

#include <math.h>

/************************************************************************

A lexical scanner to recognize numbers, symbols and the EQ

operator. When a NUMBER is found, its value is set is set tothe

appropriate float. When a NAME is found, an entry in symboltable is

created (with initial value 0.0) and the token’s value is apointer to

this entry. If a ‘==’ sequence is seen, it is returned as atoken

EQ. Spaces and tabs are ignored. Any other characters,including

a newline, are passed on as their own tokens. Based on thezcalc

calculator by ruiz@capsl.udel.edu

************************************************************************/

%}

D [0-9]

A [a-zA-Z]

AD [a-zA-Z0-9]

%%

({D}+|({D}*.{D}+)([eE][-+]?{D}+)?) {yylval.dval = atof(yytext);return NUMBER;}

{A}{AD}* {struct symtab *sp = symlook(yytext); yylval.symp = sp;return NAME;}

[ t] ;

n |

. return yytext[0];

%%

MYMAKE

# A Makefile for simple lex and yacc examples

# Comment out the proper lines below according to the scannerand

# parser generators available in your system

#LEX = lex

#YACC = yacc -d

LEX = flex

YACC = bison -d -o y.tab.c

# We assume that your C-compiler is called cc

# CC = cc -m32

# calc is the final object that we will generate, it is producedby

# the C compiler from the y.tab.o and from the lex.yy.o

calc: y.tab.o lex.yy.o

$(CC) -o calc y.tab.o lex.yy.o

# These dependency rules indicate that (1) lex.yy.o dependson

# lex.yy.c and y.tab.h and (2) lex.yy.o and y.tab.o depend oncalc.h.

# Make uses the dependencies to figure out what rules must berun when

# a file has changed.

lex.yy.o: lex.yy.c y.tab.h

lex.yy.o y.tab.o: calc.h

## This rule will use yacc to generate the files y.tab.c andy.tab.h

## from our file calc.y

y.tab.c y.tab.h: calc.y

$(YACC) -v calc.y

## this is the make rule to use lex to generate the filelex.yy.c from

## our file calc.l

lex.yy.c: calc.l

$(LEX) calc.l

## Make clean will delete all of the generated files so we canstart

## from scratch

clean:

-rm -f *.o lex.yy.c *.tab.* calc *.output

Expert Answer


Answer to The goal of this exercise is to acquaint yourself with two very powerful tools for the generation of compilers: ​flex … . . .

OR


Leave a Reply

Your email address will not be published. Required fields are marked *