mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-02-11 15:40:39 +00:00
prepared expression parser for implementation of more complex expressions
This commit is contained in:
parent
6ebe2cff5f
commit
ab33234027
@ -4,34 +4,51 @@
|
||||
#include <stdexcept>
|
||||
|
||||
#include "generator.hpp"
|
||||
#include "scanner.hpp"
|
||||
#include "errorhandler.hpp"
|
||||
|
||||
namespace Compiler
|
||||
{
|
||||
ExprParser::ExprParser (ErrorHandler& errorHandler, Context& context, Locals& locals,
|
||||
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)
|
||||
{
|
||||
Operand operand;
|
||||
operand.mType = 'l';
|
||||
operand.mInteger = value;
|
||||
if (mNextOperand)
|
||||
{
|
||||
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)
|
||||
{
|
||||
Operand operand;
|
||||
operand.mType = 'f';
|
||||
operand.mFloat = value;
|
||||
if (mNextOperand)
|
||||
{
|
||||
Operand operand;
|
||||
operand.mType = 'f';
|
||||
operand.mFloat = value;
|
||||
|
||||
mOperands.push_back (operand);
|
||||
mOperands.push_back (operand);
|
||||
|
||||
return false;
|
||||
mNextOperand = false;
|
||||
mTokenLoc = loc;
|
||||
return true;
|
||||
}
|
||||
|
||||
return Parser::parseFloat (value, loc, scanner);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
void ExprParser::reset()
|
||||
{
|
||||
mOperands.clear();
|
||||
mOperators.clear();
|
||||
mNextOperand = true;
|
||||
}
|
||||
|
||||
char ExprParser::write (std::vector<Interpreter::Type_Code>& code)
|
||||
{
|
||||
if (mOperands.empty())
|
||||
throw std::logic_error ("empty expression");
|
||||
if (mOperands.empty() && mOperators.empty())
|
||||
getErrorHandler().error ("missing expression", mTokenLoc);
|
||||
|
||||
if (mNextOperand)
|
||||
getErrorHandler().error ("syntax error in expression", mTokenLoc);
|
||||
|
||||
Operand operand = mOperands[mOperands.size()-1];
|
||||
mOperands.clear();
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <components/interpreter/types.hpp>
|
||||
|
||||
#include "parser.hpp"
|
||||
#include "tokenloc.hpp"
|
||||
|
||||
namespace Compiler
|
||||
{
|
||||
@ -24,6 +25,9 @@ namespace Compiler
|
||||
Locals& mLocals;
|
||||
Literals& mLiterals;
|
||||
std::vector<Operand> mOperands;
|
||||
std::vector<char> mOperators;
|
||||
bool mNextOperand;
|
||||
TokenLoc mTokenLoc;
|
||||
|
||||
public:
|
||||
|
||||
|
@ -43,6 +43,12 @@ namespace Compiler
|
||||
|
||||
bool Scanner::scanToken (Parser& parser)
|
||||
{
|
||||
if (mNewline)
|
||||
{
|
||||
mNewline = false;
|
||||
return parser.parseSpecial (S_newline, mPutbackLoc, *this);
|
||||
}
|
||||
|
||||
char c;
|
||||
|
||||
if (!get (c))
|
||||
@ -412,13 +418,20 @@ namespace Compiler
|
||||
// constructor
|
||||
|
||||
Scanner::Scanner (ErrorHandler& errorHandler, std::istream& inputStream)
|
||||
: mErrorHandler (errorHandler), mStream (inputStream)
|
||||
: mErrorHandler (errorHandler), mStream (inputStream), mNewline (false)
|
||||
{
|
||||
}
|
||||
|
||||
void Scanner::scan (Parser& parser)
|
||||
{
|
||||
mNewline = false;
|
||||
while (scanToken (parser));
|
||||
}
|
||||
|
||||
void Scanner::putbackNewline (const TokenLoc& loc)
|
||||
{
|
||||
mNewline = true;
|
||||
mPutbackLoc = loc;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,8 @@ namespace Compiler
|
||||
TokenLoc mLoc;
|
||||
TokenLoc mPrevLoc;
|
||||
std::istream& mStream;
|
||||
bool mNewline;
|
||||
TokenLoc mPutbackLoc;
|
||||
|
||||
public:
|
||||
|
||||
@ -78,6 +80,9 @@ namespace Compiler
|
||||
|
||||
void scan (Parser& parser);
|
||||
///< Scan a token and deliver it to the parser.
|
||||
|
||||
void putbackNewline (const TokenLoc& loc);
|
||||
///< put back a newline token
|
||||
};
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user