mirror of
https://github.com/OpenMW/openmw.git
synced 2025-03-03 21:09:41 +00:00
prepared expression parser for implementation of more complex expressions
This commit is contained in:
parent
6ebe2cff5f
commit
ab33234027
4 changed files with 73 additions and 14 deletions
|
@ -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);
|
||||||
|
|
||||||
return false;
|
mNextOperand = false;
|
||||||
|
mTokenLoc = loc;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
return false;
|
mNextOperand = false;
|
||||||
|
mTokenLoc = loc;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
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,18 +64,38 @@ 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…
Reference in a new issue