Interpreter:
- Interpreter executes each statement of a program at a time.
- It calls recursive functions for “statement”, “expression”, “factor”, “term” and “Identifier” to execute a statement.
- It allows arithmetic operations addition, subtraction, multiplication, division and exponentiation.
/***********************************************************
* This program extends the interpreter with exponentiation *
* process. *
***********************************************************/
Explanation of Solution
//interpreter.h
//Include header files
#ifndef INTERPRETER
#define INTERPRETER
#include <iostream>
#include <list>
#include <algorithm> // find
using namespace std;
//Definition of class IdNode
class IdNode
{
//Declare public methods
public:
//Declare Parameterized constructor
IdNode(char *s = "", double e = 0)
{
//Initialize variables
id = strdup(s);
value = e;
}
//Function to overload operator ==
bool operator== (const IdNode& node) const
{
/*Return true if both string are same, otherwise return false*/
return strcmp(id,node.id)==0;
}
//Declare private variables and overloading function
private:
//Declare variables
char *id;
double value;
//Declare class object
friend class Statement;
//Prototype for overloading function
friend ostream& operator<<(ostream&, const IdNode&);
};
//Definition of class Statement
class Statement
{
//Declare public functions
public :
//Constructor
Statement(){}
//Declare function getStatement()
void getStatement();
//Declare private variables
private:
//Declare variables
list<IdNode>idList;
char ch;
//Function prototypes
double factor();
double term();
double expression();
double exponent();
void readId(char*);
//Declare function to print error message
void issueError(char* s)
{
cerr << s << endl; exit(1);
}
//Function prototypes
double findValue(char*);
void processNode(char*, double);
friend ostream& operator<< (ostream&, const Statement&);
};
#endif
//interpreter.cpp
//Include header files
#include <cctype>
#include <stdio.h>
#include <string.h>
#include <string>
#include <list>
#include "interpreter.h"
//Function to find value of identifier
double Statement::findValue(char *id)
{
//Create object of class IdNode for id
IdNode tmp(id);
/*If identifier is present in IdNode list, return position */
list<IdNode>::iterator i = find(idList.begin(),idList.end(),tmp);
//If position is not end of list
if (i != idList.end())
//Return value of identifier
return i->value;
//Otherwise
else
//Print error message
issueError("Unknown variable");
// This statement will never be reached;
return 0;
}
//Function to process node
void Statement::processNode(char* id,double e)
{
/*Create object of class for IdNode for statement*/
IdNode tmp(id,e);
//If identifier is present in IdNode list find position of identifier
list<IdNode>::iterator i = find(idList.begin(),idList.end(),tmp);
//If position of identifier is not end of IdNode list
if (i != idList.end())
//Set value of identifier as value of expression
i->value = e;
//Otherwise
else
//Insert New value into list
idList.push_front(tmp);
}
/* readId() reads strings of letters and digits that start with a letter, and stores them in array passed to it as an actual parameter.*/
/* Examples of identifiers are: var1, x, pqr123xyz, aName, etc.*/
//Function to read identifier
void Statement::readId(char *id)
{
//Initialize variable i as 0
int i = 0;
//If ch is space
if (isspace(ch))
//Skip balks and read next character
cin >> ch;
//If character is alphabet
if (isalpha(ch))
{
//Read character till read a non-alphanumeric
while (isalnum(ch))
{
//Copy each character to identifier
id[i++] = ch;
//Read next character
cin.get(ch);
}
//Set last character as end of string
id[i] = '\0';
}
//Otherwise
else
//Print error message
issueError("Identifier expected");
}
//Function to find exponent
double Statement::exponent()
{
// <exponent> ::= <factor> ^ <exponent>,
double f = factor();
//If ch is operatotr ^
if (ch == '^')
//Compute power and Return it
return pow(f,exponent());
//Otherwise
else
//Return f
return f;
}
//Function factor()
double Statement::factor()
{
//Declare variables
double var, minus = 1.0;
static char id[200];
//Read character
cin >> ch;
//If ch is operator + or -
while (ch == '+' || ch == '-')
{
// take all '+'s and '-'s.
//If ch is -
if (ch == '-')
/*Set value as negative by multiplying with -1*/
minus *= -1.0;
//Read next character
cin >> ch;
}
//If ch is digit or operator dot
if (isdigit(ch) || ch == '.')
{ // Factor can be a number
//Read digits of number
cin.putback(ch);
cin >> var >> ch;
}
//If ch is paranthesis (
else if (ch == '(')
{
// or a parenthesized expression,
//Get next expression after (
var = expression();
//If character is )
if (ch == ')')
//Read next character
cin >> ch;
//Otherwise
else
//Print error message
issueError("Right paren left out");
}
//Otherwise
else
{
//Read identifier
readId(id);
//If chracter is space
if (isspace(ch))
//Read next character
cin >> ch;
//Get value of identifier
var = findValue(id);
}
//Return value
return minus * var;
}
//Function for term()
double Statement::term()
{
//Call function exponent()
double f = exponent();
//Do calculation for operators * and /
while (true)
{
//Switch statement
switch (ch)
{
//If ch is *, multiply recursively
case '*' : f *= exponent(); break;
//If ch is *, divide recursively
case '/' : f /= exponent(); break;
//Defaultly return f
default : return f;
}
}
}
//Function for expression()
double Statement::expression()
{
//Call function term()
double t = term();
//Do calculation for operators + and -
while (true)
{
//Switch statement
switch (ch)
{
//If ch is +, add recursively
case '+' : t += term(); break;
//If ch is -, subtract recursively
case '-' : t -= term(); break;
// Return f
default : return t;
}
}
}
//Function to read statement
void Statement::getStatement()
{
//Declare variables
char id[20], command[20];
double e;
//Prompt and read statement
cout << "Enter a statement: ";
cin >> ch;
//Read identifier
readId(id);
//Copy identifier to string command
strupr(strcpy(command,id));
//If command is STATUS
if (strcmp(command,"STATUS") == 0)
//Print current values of all variables
cout << *this;
//If command is PRINT
else if (strcmp(command,"PRINT") == 0)
{
//Read identifier from user
readId(id);
//Get value of identifier and print it
cout << id << " = " << findValue(id) << endl;
}
//If command is END
else if (strcmp(command,"END") == 0)
//Retun from program
exit(0);
//Otherwise
else
{
//If ch is space
if (isspace(ch))
//Read next character
cin >> ch;
//If ch is =
if (ch == '=')
{
//Read expression
e = expression();
//If ch is not ;
if (ch != ';')
//print error message
issueError("There are some extras in the statement");
//Otherwise process statement
else processNode(id,e);
}
//Otherwise print error message
else issueError("'=' is missing");
}
}
/*Function to overload operator << to print values all identifiers in list*/
ostream& operator<< (ostream& out, const Statement& s)
{
//Initialize iterator
list<IdNode>::const_iterator i = s.idList.begin();
//For each identifier
for ( ; i != s.idList.end(); i++)
//Print value of identifier
out << *i;
//Print new line
out << endl;
return out;
}
/*Function to overload operator << to print value od identifier*/
ostream& operator<< (ostream& out, const IdNode& r)
{
//Print value of identifier
out << r.id << " = " << r.value << endl;
return out;
}
//useInterpreter.cpp
//Include header files
#include "interpreter.h"
using namespace std;
//Program begins with main()
int main()
{
//Declare object of class Statement
Statement statement;
//Prompt message
cout << "The program processes statements of the following format:\n"<< "\t<id> = <expr>;\n\tprint <id>\n\tstatus\n\tend\n\n";
// This infinite loop is broken by exit(1)
while (true)
// in getStatement() or upon finding an
statement.getStatement();
//Return 0
return 0;
}
Explanation:
- Define function “exponent()” as member of class “Statement”.
- In function “exponent()”,
- It calls function “factor()”
- If next character is “^” compute exponentiation by calling function itself recursively.
- Return result.
- Function “term()” calls function “exponent()” instead of “factor()”.
Output:
The program processes statements of the following format:
<id> = <expr>;
print <id>
status
end
Enter a statement: var1=2+(2^3);
Enter a statement: var2=var1-2;
Enter a statement: var3=var2*2;
Enter a statement: status
var3 = 16
var2 = 8
var1 = 10
Enter a statement: var3=var3-4;
Enter a statement: print var3
var3 = 12
Enter a statement: end
Want to see more full solutions like this?
Chapter 5 Solutions
EBK DATA STRUCTURES AND ALGORITHMS IN C
- For function log, write the missing base case condition and the recursive call. This function computes the log of n to the base b. As an example: log 8 to the base 2 equals 3 since 8 = 2*2*2. We can find this by dividing 8 by 2 until we reach 1, and we count the number of divisions we make. You should assume that n is exactly b to some integer power. Examples: log(2, 4) -> 2 and log(10, 100) -> 2 public int log(int b, int n ) { if <<Missing base case condition>> { return 0; } else { return <<Missing a Recursive case action>> }}arrow_forwardGive two instances of functions that aren't totally tail recursive but are close. Describe a general pattern for transforming a nearly tail-recursive function into a loop, much as a tail-recursive function may be changed. Is it possible for an interpreter to identify almost tail recursion as readily as tail recursion? Please explain how.arrow_forwardDefine a recursive function (rem r b) that, given a regular expression r and a bool b, returns a new regular expression r′ that matches exactly the set of all strings s such that string bs is matched by r. We will call r′ the remainder of r after division by b. For example, if r matches {T,FF T,TFF} and b = T, then r′ can be any regular expression that matches exactly the set {ε,FF} (because T and TFF are the only strings matched by r that begin with b = T, and their remainders are ε and FF, respectively). Here are some examples of what your function could output (but these are not the only answers!): • rem (false(false+true)∗) false = (false+true)∗ • rem (false(false+true)∗) true = ∅• rem (false∗ + true∗) true = true∗• rem ((false∗)(true∗)) true = true∗ Your implementation need not output these exact regular expressions as long as it always outputs an equivalent regular expression (i.e., one that matches the same set of strings as the given answer). These are also not the only test…arrow_forward
- Please explain Crime Wave more clearly for me please there's a picture of the decription and also please comment on each line if possible on the code below to for me to have a better understanding of what each line is doing. It is in C++. Please also give the space and time complexity and the reason why. #include <stdio.h>#include <string.h>#include <math.h>#define eps 1e-6double W[105][105];int N, M;int mx[105], my[105]; // match arrdouble lx[105], ly[105]; // label arrint x[105], y[105]; // used arrint hungary(int nd) { int i; x[nd] = 1; for(i = 1; i <= M; i++) { if(y[i] == 0 && fabs(W[nd][i]-lx[nd]-ly[i]) < eps) { y[i] = 1; if(my[i] == 0 || hungary(my[i])) { my[i] = nd; return 1; } } } return 0;}double KM() { int i, j, k; double d; memset(mx, 0, sizeof(mx)); memset(my, 0, sizeof(my)); memset(lx, 0, sizeof(lx)); memset(ly, 0, sizeof(ly));…arrow_forwardGive a recursive definition for the set of all strings of a’s and b’s where all the strings are of odd lengths. (Assume, S is set of all strings of a’s and b’s where all the strings are of odd lengths. Then S = { a, b, aaa, aba, aab, abb, baa, bba, bab, bbb, aaaaa, ... )arrow_forwardConsider a function tetrahedral( ) that computes the n^th tetrahedral number for a given integer n>=0: T(n)= Tri(1)+Tri(2)+Tri(3)+...+Tri(n-1)+Tri(n) where Tri(n) is defined as Tri(n)+1+2+3+...+(n-1)+n a) Implement the function tetrahedral( ) using recursion in order to perform the repeated additions. b) Find an algebraic representation for T(n) that does not require any repeated additions. Implement the function tetrahedral( ) with a one-line definition using this formula.arrow_forward
- Give a recursive definition for the set of all strings of a’s and b’s that begins with an a and ends in a b. Say, S = { ab, aab, abb, aaab, aabb, abbb, abab..} Let S be the set of all strings of a’s and b’s that begins with a and ends in a b. The recursive definition is as follows – Base:... Recursion: If u ∈ S, then... Restriction: There are no elements of S other than those obtained from the base and recursion of S.arrow_forwardCorrect answer will be upvoted else downvoted. Computer science. Presently Nezzar has a beatmap of n particular focuses A1,A2,… ,An. Nezzar might want to reorder these n focuses so the subsequent beatmap is great. Officially, you are needed to find a change p1,p2,… ,pn of integers from 1 to n, to such an extent that beatmap Ap1,Ap2,… ,Apn is great. In case it is unthinkable, you ought to decide it. Input The primary line contains a solitary integer n (3≤n≤5000). Then, at that point, n lines follow, I-th of them contains two integers xi, yi (−109≤xi,yi≤109) — directions of point Ai. It is ensured that all focuses are unmistakable. Output In case there is no arrangement, print −1. In any case, print n integers, addressing a legitimate change p. In case there are numerous potential replies, you can print any.arrow_forwardImplement a pushdown automaton that will check if a given string is palindrome or not. To make your task easier you can assume the alphabet you are going to work on is limited to {a,b,c,d}. Your implementation can use a CYK algorithm to check if the given string is a palindrome. You’re not allowed to just check if the string is a palindrome by comparing the characters one by one from both sides, your implementation needs to be an actual pushdown automaton or CYK algorithm.arrow_forward
- For the following pairs of expressions, find a unifier for each pair if a unifier exists. If a unifierdoes not exist, explain why.(a) p(X,Y) and p(a,Z)(b) p(X,X) and p(a,b)(c) f(X,Y) and f(a,g(a))(d) q(X) and ¬q(a)arrow_forwardThe binomial coefficient C(N,k) can be defined recursively as follows: C(N,0) = 1, C(N,N) = 1, and for 0 < k < N, C(N,k) = C(N-1,k) + C(N - 1,k - 1). Write a function and give an analysis of the running time to compute the binomial coefficients as follows: A. The function is written recursively.arrow_forwardImplement Hungarian Method for assignment problem that can solve an NxN matrix in python without using Object orientation and libraries that does the algorithm itself (such as dlib).arrow_forward
- Database System ConceptsComputer ScienceISBN:9780078022159Author:Abraham Silberschatz Professor, Henry F. Korth, S. SudarshanPublisher:McGraw-Hill EducationStarting Out with Python (4th Edition)Computer ScienceISBN:9780134444321Author:Tony GaddisPublisher:PEARSONDigital Fundamentals (11th Edition)Computer ScienceISBN:9780132737968Author:Thomas L. FloydPublisher:PEARSON
- C How to Program (8th Edition)Computer ScienceISBN:9780133976892Author:Paul J. Deitel, Harvey DeitelPublisher:PEARSONDatabase Systems: Design, Implementation, & Manag...Computer ScienceISBN:9781337627900Author:Carlos Coronel, Steven MorrisPublisher:Cengage LearningProgrammable Logic ControllersComputer ScienceISBN:9780073373843Author:Frank D. PetruzellaPublisher:McGraw-Hill Education