Great Deal! Get Instant $10 FREE in Account on First Order + 10% Cashback on Every Order Order Now

PA 3 Description 1 CS 280 Programming Language Concepts Programming Assignment 3 Implementation of an Interpreter for a Simple Programming Language Programming Assignment 3 ◼ Objectives  Construction...

1 answer below »
PA 3 Description
1
CS 280
Programming Language Concepts
Programming Assignment 3
Implementation of an Interpreter for a
Simple Programming Language
Programming Assignment 3
◼ Objectives
 Construction of an interpreter for a simple programming
language based on the recursive-descent parser developed
in Programming Assignment 2.
◼ Notes:
 Read the assignment carefully to understand it.
 Understand the functionality of the interpreter, and the required
actions to be performed to execute the source code.
3
Given Files
◼ “lex.h”
◼ “lex.cpp”
 You can use your implementation, or copy and use my lexical
analyzer when I publish it.
◼ “parserIn.h”
 Modified version of “parse.h”.
◼ “parse.cpp”
 You can use your implementation, or copy and use my parse
when I publish it.
 This file will should be renamed as “parserInt.cpp” for you
submission
◼ “val.h” and “val.cpp”
 Specification and implementation of the class Value.
4
Gramma
◼ Modified grammar: Deletion of the ReadStmt and VarList rules
Prog = PROGRAM IDENT {Decl} {Stmt} END PROGRAM IDENT
Decl = (INTEGER | REAL | CHAR) : IdList
IdList = IDENT {,IDENT}
Stmt = AssigStmt | IfStmt | PrintStmt
PrintStmt = PRINT , ExprList
IfStmt = IF (LogicExpr) THEN {Stmt} END IF
AssignStmt = Var = Exp
ExprList = Expr {, Expr}
Expr = Term {(+|-) Term}
Term = SFactor {(*|/) SFactor}
SFactor = Sign Factor | Facto
LogicExpr = Expr (== | <) Exp
Var = IDENT
Sign = + | -
Factor = IDENT | ICONST | RCONST | SCONST | (Expr)
5
Example Program of our Simple Language
!Clean Program
PROGRAM circle
!If stmt test
REAL : r, a, p,
CHAR : str1, str2
= 5
a = (3.14) * r *
IF ( r == 5) THEN
p = 2 * 3.14 * a
print, "r= ", r, " a= " , a, " p= ", p
END IF
END PROGRAM circle
6
Description of the Language
1. The language has three types: INTEGAR, REAL, and CHARacter (as
string).
2. The PLUS and MINUS operators in Expr represent addition and subtraction.
3. The MULT and DIV operators in Term represent multiplication and
division.
4. The PLUS, MINUS, MULT and DIV operators are left associative.
5. MULT and DIV have higher precedence than PLUS and MINUS.
6. Unary operators for the sign have higher precedence than MULT and DIV.
7. All variables have to be declared in declaration statements.
8. An IfStmt evaluates a logical expression (LogicExpr) as a condition. If the
logical expression value is true, then the Stmt block is executed, otherwise it
is not. Though the language does not include a Boolean type, Boolean
expressions are considered as the type of evaluating LogicExpr.
9. A PrintStmt evaluates the list of expressions (ExprList), and prints thei
values in order from left to right.
7
Description of the Language
10. The ASSOP operator in the AssignStmt assigns a value to a variable. It
evaluates the Expr on the right-hand side and saves its value in memory
associated with the left-hand side variable (Var). The left-hand side variable
must be of a type that is compatible with the type of the expression value on
the right-hand side. For example, an integer variable can be assigned a real
value, and a real variable can be assigned an integer value. In either case,
conversion of the value to the type of the variable must be applied. However,
it is an e
or to assign a numeric value to a variable of a CHAR type, or to
assign a CHAR value to a numeric variable (i.e., integer or real).
11. The binary operations for addition, subtraction, multiplication, and division
are performed upon two numeric operands (i.e., integer or real) of the same
or different types. If the operands are of the same type, the type of the result
is the same type as the operator’s operands. Otherwise, the type of the result
is real. It is an e
or to have string operand to any of the arithmetic
operations.
8
Description of the Language
12. The EQUAL and LTHAN relational operators operate upon two
compatible operands. The evaluation of a logical expression, based on
EQUAL or LTHAN operation, produces either a true or false value that
controls whether the statement(s) of the selection IfStmt is executed o
not.
13. It is an e
or to use a variable in an expression before it has been assigned.
14. The unary sign operators (+ or -) are applied upon a unary numeric
operand (i.e., INTEGER or REAL).
15. The name of the program at its header must match the name of the
program at its end.
9
Implementation of an Interpreter for the
Simple Programming Language
◼ The parser includes one function per rule or nonterminal.
◼ Each function recognizes the right hand side of the rule.
 If the function needs to read a token, it can read it using
getNextToken().
 If the function needs a nonterminal symbol, it calls the function fo
that nonterminal symbol.
◼ The interpreter parses the input source code statement by
statement. For each parsed statement:
 The parse
interpreter stops if there is a lexical/syntactic e
or.
 If parsing is successful for the statement, it interprets the statement:
◼ Checks for semantic e
ors (i.e., run-time) in the statement.
◼ Stops the process of interpretation if there is a run-time e
or.
◼ Executes the statement if no e
ors found.
10
Implementation of an Interpreter for the
Simple Programming Language
 The results of an unsuccessful parsing and interpreting are a set
of e
or messages printed by the parse
interpreter functions, as
well as the e
or messages that might be detected by the lexical
analyzer.
◼ Suggested messages of the interpreter’s semantics check might
include messages such as "Run-Time E
or-Illegal Mixed Type
Operands", " Run-Time E
or-Illegal Assignment Operation",
"Run-Time E
or-Illegal Division by Zero", etc.
11
“val.h” Description
enum ValType { VINT, VREAL, VCHAR, VBOOL, VERR };
class Value {
private:
ValType T;
Int Itemp;
floatRtemp;
String Stemp;
Bool Btemp;
public:
Value() : T(VERR), Itemp(0), Rtemp(0.0){}
Value(int vi) : T(VINT), Itemp(vi) {}
Value(float vr) : T(VREAL), Itemp(0), Rtemp(vr) {}
Value(string vs) : T(VCHAR), Itemp(0), Rtemp(0.0), Stemp(vs) {}
Value(bool vb) : T(VBOOL), Btemp(vb), Itemp(0), Rtemp(0.0) {}
ValType GetType() const { return T; }
ool IsE
() const { return T == VERR; }
ool IsInt() const { return T == VINT; }
ool IsChar() const { return T == VCHAR; }
ool IsReal() const {return T == VREAL;}
ool IsBool() const {return T == VBOOL;}
12
“val.h” Description
int GetInt() const { if( IsInt() ) return Itemp; throw "RUNTIME
ERROR: Value not an integer"; }
string GetChar() const { if( IsChar() ) return Stemp; throw
"RUNTIME ERROR: Value not a string"; }
float GetReal() const { if( IsReal() ) return Rtemp; throw "RUNTIME
ERROR: Value not an integer"; }
ool GetBool() const {if(IsBool()) return Btemp; throw "RUNTIME
ERROR: Value not a boolean";}
void SetType(ValType type){ T = type;}
void SetInt(int val){ Itemp = val;}
void SetReal(float val){ Rtemp = val;}
void SetChar(string val){ Stemp = val;}
void SetBool(bool val){ Btemp = val;}
13
“val.h” Description
Overloaded operations
add op to this
Value operator+(const Value& op) const;
subtract op from this
Value operator-(const Value& op) const;
multiply this by op
Value operator*(const Value& op) const;
divide this by op
Value operato
(const Value& op) const;
compare this with op
Value operator==(const Value& op) const;
Value operato
(const Value& op) const;
friend ostream& operato
(ostream& out, const Value& op) {
if( op.IsInt() ) out
op.Itemp;
else if( op.IsChar() ) out
op.Stemp;
else if( op.IsReal()) out
op.Rtemp;
else out
"ERROR";
eturn out;
};
14
“val.h” Description
add this with op.
Applies the semantics of mixed type numeric operands
Value Value::operator+(const Value& op) const {
if( GetType() == op.GetType() ){
if( IsInt() ) return Value( Itemp + op.GetInt() );
if( IsReal() ) return Value( Rtemp + op.GetReal() );
}
else if(IsInt() && op.IsReal(){
eturn Value( (float) GetInt() + op.GetReal());
}
else if(IsReal() && op.IsInt()){
eturn Value(GetReal() + (float) op.GetInt());
}
else{
eturn Value();
}
}
Other overloaded operators are similarly implemented.
15
“val.h” Description
compare this with op for ==
Value Value::operator==(const Value& op) const {
if( GetType() == op.GetType() ){
if( IsInt() ) return Value( (bool)(Itemp == op.GetInt() ));
if( IsReal() ) return Value( (bool) (Rtemp == op.GetReal() ));
if( IsChar()) return Value( (bool) (Stemp < op.GetChar()));
}
else if(IsInt() && op.IsReal()){
eturn Value( (bool) (((float) GetInt())== op.GetReal()));
}
else if(IsReal() && op.IsInt()){
eturn Value( (bool) (GetReal() == ((float) op.GetInt())));
}
else{
eturn Value();
}
}
compare this with op for
16
“parserInt.h” Description
◼ Repository of temporaries construction using map containe
 map TempsResults;
 Each entry of TempsResults is a pair of a string and a Value
object, representing a variable name, a constant, or an expression
value and its co
esponding Value object.
◼ Queue container for Value objects
 queue * ValQue;
 Declaration of a pointer variable to a queue of Value objects
 Utilized to queue the evaluated list of expressions (ExprList) in a
PrintStmt. The values of evaluated expressions are printed out in
order from left to right by the PrintStmt.
17
“parserInt.h” Description
◼ “parserInt.h”: includes the prototype definitions of the parse
functions as in “parse.h” header file with following applied
modifications:
extern bool Var(istream& in, int& line, LexItem & tok);
extern bool LogicExpr(istream& in, int& line, Value &
etVal);
extern bool Expr(istream& in, int& line, Value &
etVal);
extern bool Term(istream& in, int& line, Value &
etVal);
extern bool SFactor(istream& in, int& line, Value &
etVal);
extern bool Factor(istream& in, int& line, int sign,
Value & retVal);
18
“parserInt.h” Description
◼ NOTE:
 All code segments available in “parserInt.h” have to be
moved to your “parserInt.cpp” file, except the defined
functions prototypes. This process is needed in order to
satisfy the requirements for linking program files on Linux
when you are submitting your work to Vocareum.
19
Testing Program Requirements
◼ “prog3.cpp”:
 You are given the testing program “prog3.cpp” that reads a file name
from the command line. The file is opened for syntax analysis and
interpretation, as a source code of the language.
 A call to Prog() function is made. If the call fails, the program should
stop and display a message as "Unsuccessful Interpretation ", and display
the number of e
ors detected. For example:
Unsuccessful Interpretation
Number of Syntax E
ors: 3
 If the call to Prog() function succeeds, the program should stop and
display the message "Successful Execution", and the program stops.
20
Testing Program Requirements
◼ Vocareum Automatic Grading
 You are provided by a set of 14 testing files associated with
Answered 22 days After Apr 27, 2021

Solution

Sandeep Kumar answered on May 20 2021
153 Votes
lex.cpp
lex.cpp
*
 * lex.cpp
 *
 * CS280 - Spring 2021
 *
#include #include #include "lex.h"
using std::map;
using namespace std;
LexItem id_or_kw(const string &lexeme, int linenum)
{
    Token tt = IDENT;
    auto kIt = kwmap.find(lexeme);
    if (kIt != kwmap.end())
        tt = kIt->second;
    return LexItem(tt, lexeme, linenum);
}
LexItem
getNextToken(istream &in, int &linenum)
{
    enum TokState
    {
        START,
        INID,
        INSTRING,
        ININT,
        INREAL,
        INCOMMENT
    } lexstate = START;
    string lexeme;
    char ch, nextch, nextchar, nextch1;
    int strtype = 0; 
0 for double quotes and 1 for single quotes
    while (in.get(ch))
    {
        switch (lexstate)
        {
        case START:
            if (ch == '\n')
                linenum++;
            if (isspace(ch))
                continue;
            lexeme = ch;
            if (isalpha(ch))
            {
                lexeme = toupper(ch);
                lexstate = INID;
            }
            else if (ch == '"')
            {
                lexstate = INSTRING;
            }
            else if (ch == '\'')
            {
                strtype = 1;
                lexstate = INSTRING;
            }
            else if (isdigit(ch))
            {
                lexstate = ININT;
            }
            else if (ch == '!')
            {
                lexstate = INCOMMENT;
            }
            else
            {
                Token tt = ERR;
                switch (ch)
                {
                case '+':
                    tt = PLUS;
                    
eak;
                case '-':
                    tt = MINUS;
                    
eak;
                case '*':
                    tt = MULT;
                    
eak;
                case '/':
                    nextch1 = in.peek();
                    if (nextch1 == '/')
                    {
                        in.get(ch);
                        tt = CONCAT;
                        
eak;
                    }
                    tt = DIV;
                    
eak;
                case '=':
                    nextchar = in.peek();
                    if (nextchar == '=')
                    {
                        in.get(ch);
                        tt = EQUAL;
                        
eak;
                    }
                    tt = ASSOP;
                    
eak;
                case '(':
                    tt = LPAREN;
                    
eak;
                case ')':
                    tt = RPAREN;
                    
eak;
                case ':':
                    tt = COLON;
                    
eak;
                case ',':
                    tt = COMA;
                    
eak;
                case '<':
                    tt = LTHAN;
                    
eak;
                case '.':
                    nextch = in.peek();
                    if (isdigit(nextch))
                    {
                        lexstate = INREAL;
                        continue;
                    }
                    else
                    {
                        lexeme += nextch;
                        return LexItem(ERR, lexeme, linenum);
                        cout 
 "Here what?" 
 endl;
                    }
                }
                return LexItem(tt, lexeme, linenum);
            }
            
eak;
        case INID:
            if (isalpha(ch) || isdigit(ch))
            {
                ch = toupper(ch);
                lexeme += ch;
            }
            else
            {
                in.putback(ch);
                return id_or_kw(lexeme, linenum);
            }
            
eak;
        case INSTRING:
            if (ch == '\n')
            {
                return LexItem(ERR, lexeme, linenum);
            }
            lexeme += ch;
            if (ch == '"' && strtype == 0)
            {
                lexeme = lexeme.substr(1, lexeme.length() - 2);
                return LexItem(SCONST, lexeme, linenum);
            }
            else if (ch == '\'' && strtype == 1)
            {
                lexeme = lexeme.substr(1, lexeme.length() - 2);
                return LexItem(SCONST, lexeme, linenum);
            }
            
eak;
        case ININT:
            if (isdigit(ch))
            {
                lexeme += ch;
            }
            else if (ch == '.')
            {
                lexstate = INREAL;
                in.putback(ch);
            }
            else
            {
                in.putback(ch);
                return LexItem(ICONST, lexeme, linenum);
            }
            
eak;
        case INREAL:
            if (ch == '.' && isdigit(in.peek()))
            {
                lexeme += ch;
            }
            else if (isdigit(ch))
            {
                lexeme += ch;
            }
            else if (ch == '.' && !isdigit(in.peek()))
            {
                return LexItem(ERR, lexeme, linenum);
            }
            else
            {
                in.putback(ch);
                return LexItem(RCONST, lexeme, linenum);
            }
            
eak;
        case INCOMMENT:
            if (ch == '\n')
            {
                ++linenum;
                lexstate = START;
            }
            
eak;
        }
    } 
end of while loop
    if (in.eof())
        return LexItem(DONE, "", linenum);
    return LexItem(ERR, "some strange I/O e
or", linenum);
}
ostream &operato
(ostream &out, const LexItem &tok)
{
    Token tt = tok.GetToken();
    out 
 tokenPrint[tt];
    if (tt == IDENT || tt == ICONST || tt == SCONST || tt == RCONST || tt == ERR)
    {
        out 
 "(" 
 tok.GetLexeme() 
 ")";
    }
    return out;
}
lex.h
*
* lex.h
*
* CS280
* Spring 2021
*
#ifndef LEX_H_
#define LEX_H_
#include #include #include using namespace std;
Definition of all the possible token types
enum Token
{
    
keywords
    PROGRAM,
    PRINT,
    READ,
    INTEGER,
    END,
    IF,
    THEN,
    REAL,
    CHAR,
    
an identifie
    IDENT,
    
an integer, real, and string constant
    ICONST,
    RCONST,
    SCONST,
    
the operators, parens, semicolon
    PLUS,
    MINUS,
    MULT,
    DIV,
    ASSOP,
    LPAREN,
    RPAREN,
    COMA,
    EQUAL,
    LTHAN,
    CONCAT,
    COLON,
    
any e
or returns this token
    ERR,
    
when completed (EOF), return this token
    DONE
};
static map tokenPrint = {
    {PROGRAM, "PROGRAM"},
    {READ, "READ"},
    {INTEGER, "INTEGER"},
    {REAL, "REAL"},
    {CHAR, "CHAR"},
    {PRINT, "PRINT"},
    {IF, "IF"},
    {END, "END"},
    {THEN, "THEN"},
    {IDENT, "IDENT"},
    {ICONST, "ICONST"},
    {RCONST, "RCONST"},
    {SCONST, "SCONST"},
    {PLUS, "PLUS"},
    {MINUS, "MINUS"},
    {MULT, "MULT"},
    {DIV, "DIV"},
    {ASSOP, "ASSOP"},
    {LPAREN, "LPAREN"},
    {RPAREN, "RPAREN"},
    {COLON, "COLON"},
    {COMA, "COMA"},
    {EQUAL, "EQUAL"},
    {LTHAN, "LTHAN"},
    {CONCAT, "CONCAT"},
    {ERR, "ERR"},
    {DONE, "DONE"},
};
static map kwmap = {
    {"PROGRAM", PROGRAM},
    {"READ", READ},
    {"INTEGER", INTEGER},
    {"REAL", REAL},
    {"CHAR", CHAR},
    {"PRINT", PRINT},
    {"IF", IF},
    {"THEN", THEN},
    {"END", END},
};
Class definition of LexItem
class LexItem
{
    Token token;
    string lexeme;
    int lnum;
public:
    LexItem()
    {
        token = ERR;
        lnum = -1;
    }
    LexItem(Token token, string lexeme, int line)
    {
        this->token = token;
        this->lexeme = lexeme;
        this->lnum = line;
    }
    bool operator==(const Token token) const { return this->token == token; }
    bool operator!=(const Token token) const { return this->token != token; }
    Token GetToken() const { return token; }
    string GetLexeme() const { return lexeme; }
    int GetLinenum() const { return lnum; }
};
extern ostream &operato
(ostream &out, const LexItem &tok);
extern LexItem id_or_kw(const string &lexeme, int linenum);
extern LexItem getNextToken(istream &in, int &linenum);
#endif /* LEX_H_...
SOLUTION.PDF

Answer To This Question Is Available To Download

Related Questions & Answers

More Questions »

Submit New Assignment

Copy and Paste Your Assignment Here