In: Computer Science
***Convert the C++ to Python***
#include <iostream>
using std::cout;
using std::cin;
using std::endl;
int charClass;
char lexeme[100];
char str[200];
char nextChar;
const int LETTER = 0;
const int DIGIT = 1;
const int UNKNOWN = -1;
const int OPAREN = 2;
const int CPAREN = 3;
const int PLUS = 4;
const int MINUS = 5;
const int MUL = 6;
const int DIV = 7;
const int ID_CODE = 100;
const int PLUS_CODE = 101;
const int MINUS_CODE = 102;
const int AST_CODE = 103;
const int SLASH_CODE = 104;
const int LEFT_PAREN_CODE = 105;
const int RIGHT_PAREN_CODE = 106;
const int NUM_CODE = 107;
int lexLen;
int nextToken;
int strcnt;
int error = 0;
void addChar();
void getChar();
void getNonBlank();
void lex();
void expr();
void term();
void factor();
void ovalue();
int main()
{
int test;
cout << "Enter an expression: ";
cin >> str;
strcnt=0;
nextChar = str[strcnt++];
lex();
cout << "Call lex /* returns " << nextToken << "
*/\n";
/*****************************************************************************
THIS SEGMENT OF CODE HAS BEEN COMMENTED
OUT
ITS PURPOSE IS TO CONTINUALLY CALL LEX
UNTIL THE INPUT HAS BEEN EXHAUSTED
while (nextChar != '\0')
{
test = lex();
cout << test << endl;
}
END COMMENTED OUT SEGMENT OF CODE
*****************************************************************************/
expr(); /* begin recursive decent parsing */
if (nextChar == '\0')
{
if (error)
cout << "PARSE
FAILED\n\n";
else
cout << "PARSE
SUCCESSFUL\n\n";
}
else
{
cout << "PARSE FAILED\n\n";
}
return 0;
}
/* addChar - a function to add nextChar to lexeme */
void addChar()
{
if (lexLen <= 99)
{
lexeme[lexLen++] = nextChar;
}
else
{
cout << "Error - lexeme is too
long\n";
}
}
/* getChar - a function to get the next character of input and
determine its character class */
void getChar()
{
/* do whatever is required to get the next character from input and
put it in nextChar */
if (isalpha(nextChar))
{
charClass = LETTER;
}
else if (isdigit(nextChar))
{
charClass = DIGIT;
}
else if (nextChar == '(')
{
charClass = OPAREN;
}
else if (nextChar == ')')
{
charClass = CPAREN;
}
else if (nextChar == '+')
{
charClass = PLUS;
}
else if (nextChar == '-')
{
charClass = MINUS;
}
else if (nextChar == '*')
{
charClass = MUL;
}
else if (nextChar == '/')
{
charClass = DIV;
}
else
{
charClass = UNKNOWN;
}
nextChar = str[strcnt++];
}
/* getNonBlank - a function that calles getChar until it returns
a non-whitespace character */
void getNonBlank()
{
while (isspace(nextChar))
{
getChar();
}
}
/* lex - a simple lexical analyzer */
void lex()
{
int retval;
lexLen = 0;
static int first = 1;
/* If it is the first call to lex, initialize by calling getChar
*/
if (first)
{
getChar();
first = 0;
}
getNonBlank();
/* process identifiers */
if (charClass == LETTER)
{
addChar();
getChar();
while ((charClass == LETTER) || (charClass ==
DIGIT))
{
addChar();
getChar();
}
retval = ID_CODE;
}
else if (charClass == DIGIT)
{
addChar();
getChar();
while (charClass == DIGIT)
{
addChar();
getChar();
}
retval = NUM_CODE;
}
else if (charClass == PLUS)
{
getChar();
retval = PLUS_CODE;
}
else if (charClass == MINUS)
{
getChar();
retval = MINUS_CODE;
}
else if (charClass == MUL)
{
getChar();
retval = AST_CODE;
}
else if (charClass == DIV)
{
getChar();
retval = SLASH_CODE;
}
else if (charClass == OPAREN)
{
getChar();
retval = LEFT_PAREN_CODE;
}
else if (charClass == CPAREN)
{
getChar();
retval = RIGHT_PAREN_CODE;
}
else
{
retval = UNKNOWN;
}
nextToken = retval;
}
void expr()
{
cout << "Enter <expr>\n";
term();
while ((nextToken == PLUS_CODE) ||
(nextToken ==
MINUS_CODE))
{
lex();
cout << "Call lex /* returns " <<
nextToken << " */\n";
term();
}
cout << "Exit <expr>\n";
}
void term()
{
cout << "Enter <term>\n";
factor();
while ((nextToken == AST_CODE) ||
(nextToken ==
SLASH_CODE))
{
lex();
cout << "Call lex /* returns " <<
nextToken << " */\n";
factor();
}
cout << "Exit <term>\n";
}
void factor()
{
cout << "Enter <factor>\n";
if (nextToken == ID_CODE)
{
lex();
cout << "Call lex /* returns " <<
nextToken << " */\n";
}
else if (nextToken == LEFT_PAREN_CODE)
{
lex();
cout << "Call lex /* returns " <<
nextToken << " */\n";
expr();
if (nextToken == RIGHT_PAREN_CODE)
{
lex();
cout << "Call lex /* returns "
<< nextToken << " */\n";
}
else
{
error = 1;
}
}
else
{
error = 1;
}
cout << "Exit <factor>\n";
}
void ovalue()
{
if (nextToken == ID_CODE)
cout << lexeme;
else if (nextToken == NUM_CODE)
cout << "Number";
else if (nextToken == PLUS_CODE)
cout << "+";
else if (nextToken == MINUS_CODE)
cout << "-";
else if (nextToken == AST_CODE)
cout << "*";
else if (nextToken == SLASH_CODE)
cout << "/";
else if (nextToken == LEFT_PAREN_CODE)
cout << "(";
else if (nextToken == RIGHT_PAREN_CODE)
cout << ")";
else if (nextToken == UNKNOWN)
cout << "????";
}
The given C++ code, converted to python is given below. I have commented the code as and where any explanations were needed.
charClass = 0
lexeme = ""
str1 = "" #str is a method in python
nextChar = ""
#Variables cannot be declared constants in python, to emulate
that
#we define them as values returned by methods in a class
#thus they can't be modified
class Constant:
def letter(self):
return 0
def digit(self):
return 1
def unknown():
return -1
def oparen():
return 2
def cparen();
return 3
def plus():
return 4
def minus():
return 5
def mul():
return 6
def div():
return 7
def id_code():
return 100
def plus_code():
return 101
def minus_code():
return 102
def ast_code():
return 103
def slash_code():
return 104
def left_paren_code():
return 105
def right_paren_code():
return 106
def num_code():
return 107
lexLen = 0
nextToken = 0
strcnt = 0
error = False
const = Constant()
def addChar():
#declare the scope of global variables
global lexLen
global lexeme
if lexLen <= 99:
lexeme.append(nextChar)
lexLen = lexLen + 1
else:
print("Error - lexeme is too long\n")
def getChar():
#declare the scope of global variables
global nextChar
global const
global strcnt
if nextChar.isalpha():
charClass = const.letter()
elif nextChar.isdigit():
charClass = const.digit()
elif nextChar == "(":
charClass = const.oparen()
elif nextChar == ")":
charClass = const.cparen()
elif nextChar == "+":
charClass = const.plus()
elif nextChar == "-":
charClass = const.minus()
elif nextChar == "*":
charClass = const.mul()
elif nextChar == "/":
charClass = const.div()
else:
charClass = const.unknown()
nextChar = str1[strcnt]
strcnt = strcnt + 1
def getNonBlank():
#declare the scope of global variables
global nextChar
while nextChar.isspace():
getChar()
def lex():
#declare the scope of global variables
global charClass
global nextToken
global const
global lexLen
retval = 0
lexLen = 0
first = True
if first == True:
getChar()
first = False
getNonBlank()
if charClass == const.letter():
addChar()
getChar()
while charClass == const.letter() or charClass =
const.digit():
addChar()
getChar()
retval = const.id_code()
elif charClass == const.digit():
addChar()
getChar()
while charClass == const.digit():
addChar()
getChar()
retval = const.num_code()
elif charClass == const.plus():
getChar()
retval = const.plus_code()
elif charClass == const.minus():
getChar()
retval = const.minus_code()
elif charClass == const.mul():
getChar()
retval = const.ast_code()
elif charClass = const.div():
getChar()
retval = const.slash_code()
elif charClass = const.oparen():
getChar()
retval = const.left_paren_code()
elif charClass = const.cparen():
getChar()
retval = const.right_paren_code()
else:
retval = const.unknown()
nextToken = retval
def expr():
#declare the scope of global variables
global nextToken
global const
print("Enter <expr>\n")
term()
if nextToken == const.plus_code() or nextToken ==
const.minus_code():
lex()
print("call lex /* returns {} */\n".format(nextToken))
term()
print("Exit <expr>\n")
def term():
#declare the scope of global variables
global nextToken
global const
print("Enter <term>\n")
factor()
while nextToken == const.ast_code() or nextToken ==
const.slash_code():
lex()
print("call lex /* returns {} */\n".format(nextToken))
factor()
print("Exit <term>\n")
def factor():
#declare the scope of global variables
global nextToken
global const
global error
print("Enter <factor>/n")
if nextToken == const.id_code():
lex():
print("call lex /* returns {} */\n".format(nextToken))
elif nextToken == const.left_paren_code():
lex():
print("call lex /* returns {} */\n".format(nextToken))
expr()
if nextToken == const.right_paren_code():
lex():
print("call lex /* returns {} */\n".format(nextToken))
else:
error = True
else:
error = True
print("Exit <factor>\n")
def ovalue():
#declare the scope of global variables
global nextToken
global const
global lexeme
if nextToken == const.id_code():
print(lexeme),
elif nextToken == const.num_code():
print("Number"),
elif nextToken == const.plus_code():
print("+"),
elif nextToken == const.minus_code():
print("-"),
elif nextToken == const.ast_code():
print("*"),
elif nextToken == const.slash_code():
print("/"),
elif nextToken == const.left_paren_code():
print("("),
elif nextToken == const.right_paren_code():
print(")"),
else:
print("????")
if __name__ == "__main__": #main method
global str1
global strcnt
global nextChar
global error
test = 0
str1 = str(raw_input("Enter an expression: "))
strcnt = 0
nextChar = str1[strcnt]
strcnt = strcnt + 1
lex()
'''
/*******************************************************************
THIS SEGMENT OF CODE HAS BEEN COMMENTED OUT ITS PURPOSE IS TO
CONTINUALLY CALL LEX UNTIL THE INPUT HAS BEEN EXHAUSTED
while strcnt != len(str1):
test = lex()
print(test)
END COMMENTED OUT SEGMENT OF CODE
********************************************************************/
'''
if strcnt == len(str1):
if error == True:
print("PARSE FAILED\n\n")
else:
print("PARSE SUCCESSFUL\n\n")
else:
print("PARSE FAILED\n\n")
Indentation
Screenshots: