Skip to content

Commit

Permalink
changed how parser is called; added new translate function
Browse files Browse the repository at this point in the history
instead of creating a single parser instance for the whole program
(in main), a parser instance is created when needed (since there are
no member variables that need to be kept between parse calls

implemented a new translator function setInput() to translate a line
and return the status of the translate; if successful then the rpn
output list can be obtained, otherwise the error can be obtained;
this function instances its own parser to parse the input

test routine parseInput() rewritten to instance its own parser
test routine translateInput() rewritten to use new Translator
  setInput() function along with new functions for returning error
  token and message
  • Loading branch information
thunder422 committed Nov 10, 2012
1 parent 30dc86d commit a88ed2f
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 72 deletions.
7 changes: 3 additions & 4 deletions ibcp.cpp
Expand Up @@ -151,8 +151,8 @@ bool ibcpVersion(QTextStream &cout, const QString &name, int argc, char *argv[])


// prototype for test function
bool ibcpTest(QTextStream &cout, Translator &translator, Parser &parser,
int argc, char *argv[]);
bool ibcpTest(QTextStream &cout, Translator &translator, int argc,
char *argv[]);


int main(int argc, char *argv[])
Expand Down Expand Up @@ -187,9 +187,8 @@ int main(int argc, char *argv[])
cout << "Table initialization successful." << endl;

Translator translator(Table::instance());
Parser parser(Table::instance());

if (!ibcpTest(cout, translator, parser, argc, argv))
if (!ibcpTest(cout, translator, argc, argv))
{
qWarning("usage: %s -v -t <test_file>|-tp|-te|-tt",
qPrintable(programName));
Expand Down
64 changes: 16 additions & 48 deletions test_ibcp.cpp
Expand Up @@ -212,8 +212,8 @@
#include "parser.h"
#include "translator.h"

void parseInput(QTextStream &cout, Parser &parser, const QString &testInput);
void translateInput(QTextStream &cout, Translator &translator, Parser &parser,
void parseInput(QTextStream &cout, const QString &testInput);
void translateInput(QTextStream &cout, Translator &translator,
const QString &testInput, bool exprMode);
bool printToken(QTextStream &cout, Token *token, bool tab);
void printOutput(QTextStream &cout, const QString &header,
Expand All @@ -224,8 +224,7 @@ void printError(QTextStream &cout, Token *token, const QString &error);

// function to process a test input file specified on the command line
// or accept input lines from the user
bool ibcpTest(QTextStream &cout, Translator &translator, Parser &parser,
int argc, char *argv[])
bool ibcpTest(QTextStream &cout, Translator &translator, int argc, char *argv[])
{
extern char *programName;

Expand Down Expand Up @@ -332,13 +331,13 @@ bool ibcpTest(QTextStream &cout, Translator &translator, Parser &parser,
switch (testMode)
{
case testParser:
parseInput(cout, parser, inputLine);
parseInput(cout, inputLine);
break;
case testExpression:
translateInput(cout, translator, parser, inputLine, true);
translateInput(cout, translator, inputLine, true);
break;
case testTranslator:
translateInput(cout, translator, parser, inputLine, false);
translateInput(cout, translator, inputLine, false);
break;
}
}
Expand All @@ -355,8 +354,9 @@ bool ibcpTest(QTextStream &cout, Translator &translator, Parser &parser,


// function to parse an input line and print the resulting tokens
void parseInput(QTextStream &cout, Parser &parser, const QString &testInput)
void parseInput(QTextStream &cout, const QString &testInput)
{
Parser parser(Table::instance());
Token *token;
bool more;

Expand All @@ -378,59 +378,27 @@ void parseInput(QTextStream &cout, Parser &parser, const QString &testInput)

// function to parse an input line, translate to an RPN list
// and output the resulting RPN list
void translateInput(QTextStream &cout, Translator &translator, Parser &parser,
void translateInput(QTextStream &cout, Translator &translator,
const QString &testInput, bool exprMode)
{
Token *token;
Token *orgToken;
TokenStatus status;

translator.start(exprMode);
parser.setInput(QString(testInput));
do {
// set parser operand state from translator
parser.setOperandState(translator.getOperandState());
orgToken = token = parser.getToken();
if (token->isType(Error_TokenType))
{
printError(cout, token, token->string());
delete token;
translator.cleanUp();
return;
}
//printToken(cout, token, tab);
status = translator.addToken(token);
}
while (status == Good_TokenStatus);
if (status == Done_TokenStatus)
if (translator.setInput(testInput, exprMode))
{
QList<RpnItem *> *rpnList = translator.getResult();
QList<RpnItem *> *rpnList = translator.output();
printOutput(cout, "Output", *rpnList);
while (!rpnList->isEmpty())
{
delete rpnList->takeLast();
}
delete rpnList;
}
else // error occurred, output it
else // translate error occurred
{
// token pointer is set to cause of error
printError(cout, token, QString(token->message(status)));
if (token == orgToken)
{
// only deleted error token if it's the original token
// returned from the parser, if not then this token is
// in the output list and will be deleted by the
// clean_up() function (the original token has been
// already been deleted by the Translator) XXX
delete token;
}
else // check if token is open paren
Token *token = translator.errorToken();
printError(cout, token, translator.errorMessage());
if (!token->isType(Error_TokenType))
{
translator.deleteOpenParen(token);
cout << endl; // FIXME not needed, here to match current results
}
translator.cleanUp();
cout << endl; // FIXME not needed, here to match current results
}
}

Expand Down
4 changes: 3 additions & 1 deletion token.h
Expand Up @@ -70,9 +70,11 @@ class Token {
m_reference = false;
m_subCode = None_SubCode;
}
~Token(void)
Token(const Token &token) // copy constructor
{
*this = token;
}
~Token(void) {}

// column and length access functions
int column(void)
Expand Down
65 changes: 65 additions & 0 deletions translator.cpp
Expand Up @@ -374,7 +374,9 @@
// 2012-11-01 removed immediate command support

#include "translator.h"
#include "token.h"
#include "table.h"
#include "parser.h"
#include "tokenhandlers.h"


Expand Down Expand Up @@ -490,6 +492,69 @@ TokenStatus Translator::variableErrStatus(DataType dataType)
}


// function to parse and translate an input line to an RPN output list
//
// - returns true if successful, use output() to get RPN output list
// - returns false if failed, use errorToken() and errorMessage()
// to get token error occurred at and the error message

bool Translator::setInput(const QString &input, bool exprMode)
{
Token *token;
Token *parsedToken;
TokenStatus status;

Parser parser(m_table);
parser.setInput(input);

m_exprMode = exprMode; // save flag
// (expression mode for testing)
m_mode = m_exprMode ? Expression_TokenMode : Command_TokenMode;

m_output = new QList<RpnItem *>;
m_state = Initial_State;

do {
// set parser operand state from translator
parser.setOperandState(m_state == Operand_State
|| m_state == OperandOrEnd_State);
token = parsedToken = parser.getToken();
if (token->isType(Error_TokenType))
{
setErrorToken(token);
// XXX determine error code from what's expected next
m_errorMessage = token->string();
cleanUp();
return false;
}
status = addToken(token);
}
while (status == Good_TokenStatus);

if (status != Done_TokenStatus)
{
// token pointer is set to cause of error
// check if token is the parsed token or is an open paren
if (token == parsedToken || token->hasTableEntry()
&& token->isCode(OpenParen_Code))
{
// token is not already in the output list
setErrorToken(token);
}
else // token is in the rpn output list
{
// make a copy of the token to save
setErrorToken(new Token(*token));
}
m_errorMessage = token->message(status);
cleanUp();
return false;
}
// TODO check if stacks are empty
return true;
}


// function to add a token to the output list, but token may be placed
// on hold stack pending adding it to the output list so that higher
// precedence tokens may be added to the list first
Expand Down
51 changes: 32 additions & 19 deletions translator.h
Expand Up @@ -165,31 +165,35 @@ class Translator {
TokenMode m_mode; // current assignment mode
QStack<CmdItem> m_cmdStack; // stack of commands waiting processing
bool m_exprMode; // expression only mode active flag
Token *m_errorToken; // token when error occurred
QString m_errorMessage; // message of error that occurred

public:
Translator(Table &table): m_table(table), m_output(NULL),
m_pendingParen(NULL) {}
void start(bool exprMode = false)
m_pendingParen(NULL), m_errorToken(NULL) {}
~Translator(void)
{
m_exprMode = exprMode; // save flag
m_output = new QList<RpnItem *>;
m_state = Initial_State;
// (expression mode for testing)
m_mode = m_exprMode ? Expression_TokenMode : Command_TokenMode;
}
// function to access if operand state
bool getOperandState(void)
{
return m_state == Operand_State || m_state == OperandOrEnd_State;
if (m_errorToken != NULL)
{
delete m_errorToken;
}
}
TokenStatus addToken(Token *&token);
QList<RpnItem *> *getResult(void) // only call when add_token returns Done

bool setInput(const QString &input, bool exprMode = false);
QList<RpnItem *> *output(void) // only call when setInput() returns true
{
QList<RpnItem *> *list = m_output;
m_output = NULL;
return list;
}
void cleanUp(void); // only call when add_token returns an error
Token *errorToken(void) // only call when setInput() returns false
{
return m_errorToken;
}
QString errorMessage(void) // only call when setInput() returns false
{
return m_errorMessage;
}

private:
enum Match {
Expand All @@ -199,6 +203,7 @@ class Translator {
sizeof_Match
};

TokenStatus addToken(Token *&token);
TokenStatus processOperand(Token *&token);
TokenStatus endExpressionError(void);
bool processUnaryOperator(Token *&token, TokenStatus &status);
Expand All @@ -214,8 +219,10 @@ class Translator {
TokenStatus expressionEnd(void);
TokenStatus parenStatus(void);
TokenStatus getExprDataType(DataType &dataType);
void deleteOpenParen(Token *token);
void deleteCloseParen(Token *token);
TokenStatus callCommandHandler(Token *&token);
void cleanUp(void); // only call when addToken() returns error

// COMMAND SPECIFIC FUNCTIONS
TokenStatus addPrintCode(void);
Expand All @@ -228,11 +235,17 @@ class Translator {
static TokenStatus variableErrStatus(DataType dataType);
static DataType equivalentDataType(DataType dataType);

public:
// function to delete an open paren token
// (public to be used to delete token to prevent memory leak)
void deleteOpenParen(Token *token);
// set error token (deleting any previous error token first)
void setErrorToken(Token *errorToken)
{
if (m_errorToken != NULL)
{
delete m_errorToken;
}
m_errorToken = errorToken;
}

public:
// token handler friend function definitions section
friend TokenStatus Operator_Handler(Translator &t, Token *&token);
friend TokenStatus Equal_Handler(Translator &t, Token *&token);
Expand Down

0 comments on commit a88ed2f

Please sign in to comment.