prepared expression parser for implementation of more complex expressions

actorid
Marc Zinnschlag 15 years ago
parent 6ebe2cff5f
commit ab33234027

@ -4,34 +4,51 @@
#include <stdexcept> #include <stdexcept>
#include "generator.hpp" #include "generator.hpp"
#include "scanner.hpp"
#include "errorhandler.hpp"
namespace Compiler namespace Compiler
{ {
ExprParser::ExprParser (ErrorHandler& errorHandler, Context& context, Locals& locals, ExprParser::ExprParser (ErrorHandler& errorHandler, Context& context, Locals& locals,
Literals& literals) Literals& literals)
: Parser (errorHandler, context), mLocals (locals), mLiterals (literals) : Parser (errorHandler, context), mLocals (locals), mLiterals (literals),
mNextOperand (true)
{} {}
bool ExprParser::parseInt (int value, const TokenLoc& loc, Scanner& scanner) bool ExprParser::parseInt (int value, const TokenLoc& loc, Scanner& scanner)
{ {
Operand operand; if (mNextOperand)
operand.mType = 'l'; {
operand.mInteger = value; Operand operand;
operand.mType = 'l';
operand.mInteger = value;
mOperands.push_back (operand); mOperands.push_back (operand);
mNextOperand = false;
mTokenLoc = loc;
return true;
}
return false; return Parser::parseInt (value, loc, scanner);
} }
bool ExprParser::parseFloat (float value, const TokenLoc& loc, Scanner& scanner) bool ExprParser::parseFloat (float value, const TokenLoc& loc, Scanner& scanner)
{ {
Operand operand; if (mNextOperand)
operand.mType = 'f'; {
operand.mFloat = value; Operand operand;
operand.mType = 'f';
operand.mFloat = value;
mOperands.push_back (operand); mOperands.push_back (operand);
mNextOperand = false;
mTokenLoc = loc;
return true;
}
return false; return Parser::parseFloat (value, loc, scanner);
} }
bool ExprParser::parseName (const std::string& name, const TokenLoc& loc, bool ExprParser::parseName (const std::string& name, const TokenLoc& loc,
@ -47,19 +64,39 @@ namespace Compiler
bool ExprParser::parseSpecial (int code, const TokenLoc& loc, Scanner& scanner) bool ExprParser::parseSpecial (int code, const TokenLoc& loc, Scanner& scanner)
{ {
if (code==Scanner::S_comma)
{
// end marker
mTokenLoc = loc;
return false;
}
if (code==Scanner::S_newline)
{
// end marker
mTokenLoc = loc;
scanner.putbackNewline (loc);
return false;
}
return Parser::parseSpecial (code, loc, scanner); return Parser::parseSpecial (code, loc, scanner);
} }
void ExprParser::reset() void ExprParser::reset()
{ {
mOperands.clear(); mOperands.clear();
mOperators.clear();
mNextOperand = true;
} }
char ExprParser::write (std::vector<Interpreter::Type_Code>& code) char ExprParser::write (std::vector<Interpreter::Type_Code>& code)
{ {
if (mOperands.empty()) if (mOperands.empty() && mOperators.empty())
throw std::logic_error ("empty expression"); getErrorHandler().error ("missing expression", mTokenLoc);
if (mNextOperand)
getErrorHandler().error ("syntax error in expression", mTokenLoc);
Operand operand = mOperands[mOperands.size()-1]; Operand operand = mOperands[mOperands.size()-1];
mOperands.clear(); mOperands.clear();

@ -6,6 +6,7 @@
#include <components/interpreter/types.hpp> #include <components/interpreter/types.hpp>
#include "parser.hpp" #include "parser.hpp"
#include "tokenloc.hpp"
namespace Compiler namespace Compiler
{ {
@ -24,6 +25,9 @@ namespace Compiler
Locals& mLocals; Locals& mLocals;
Literals& mLiterals; Literals& mLiterals;
std::vector<Operand> mOperands; std::vector<Operand> mOperands;
std::vector<char> mOperators;
bool mNextOperand;
TokenLoc mTokenLoc;
public: public:

@ -43,6 +43,12 @@ namespace Compiler
bool Scanner::scanToken (Parser& parser) bool Scanner::scanToken (Parser& parser)
{ {
if (mNewline)
{
mNewline = false;
return parser.parseSpecial (S_newline, mPutbackLoc, *this);
}
char c; char c;
if (!get (c)) if (!get (c))
@ -412,13 +418,20 @@ namespace Compiler
// constructor // constructor
Scanner::Scanner (ErrorHandler& errorHandler, std::istream& inputStream) Scanner::Scanner (ErrorHandler& errorHandler, std::istream& inputStream)
: mErrorHandler (errorHandler), mStream (inputStream) : mErrorHandler (errorHandler), mStream (inputStream), mNewline (false)
{ {
} }
void Scanner::scan (Parser& parser) void Scanner::scan (Parser& parser)
{ {
mNewline = false;
while (scanToken (parser)); while (scanToken (parser));
} }
void Scanner::putbackNewline (const TokenLoc& loc)
{
mNewline = true;
mPutbackLoc = loc;
}
} }

@ -22,6 +22,8 @@ namespace Compiler
TokenLoc mLoc; TokenLoc mLoc;
TokenLoc mPrevLoc; TokenLoc mPrevLoc;
std::istream& mStream; std::istream& mStream;
bool mNewline;
TokenLoc mPutbackLoc;
public: public:
@ -78,6 +80,9 @@ namespace Compiler
void scan (Parser& parser); void scan (Parser& parser);
///< Scan a token and deliver it to the parser. ///< Scan a token and deliver it to the parser.
void putbackNewline (const TokenLoc& loc);
///< put back a newline token
}; };
} }

Loading…
Cancel
Save