1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2024-12-29 03:19:44 +00:00
OpenMW/components/compiler/scriptparser.cpp

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

98 lines
2.6 KiB
C++
Raw Normal View History

#include "scriptparser.hpp"
#include "errorhandler.hpp"
#include "scanner.hpp"
#include "skipparser.hpp"
namespace Compiler
{
2014-02-14 11:23:00 +00:00
ScriptParser::ScriptParser(ErrorHandler& errorHandler, const Context& context, Locals& locals, bool end)
: Parser(errorHandler, context)
, mOutput(locals)
, mLineParser(errorHandler, context, locals, mOutput.getLiterals(), mOutput.getCode())
2010-06-30 17:58:25 +00:00
, mControlParser(errorHandler, context, locals, mOutput.getLiterals())
, mEnd(end)
{
}
2022-09-22 18:26:05 +00:00
Interpreter::Program ScriptParser::getProgram() const
{
return mOutput.getProgram();
}
bool ScriptParser::parseName(const std::string& name, const TokenLoc& loc, Scanner& scanner)
{
mLineParser.reset();
if (mLineParser.parseName(name, loc, scanner))
scanner.scan(mLineParser);
return true;
}
bool ScriptParser::parseKeyword(int keyword, const TokenLoc& loc, Scanner& scanner)
{
if (keyword == Scanner::K_while || keyword == Scanner::K_if || keyword == Scanner::K_elseif)
2010-06-30 17:58:25 +00:00
{
mControlParser.reset();
if (mControlParser.parseKeyword(keyword, loc, scanner))
scanner.scan(mControlParser);
2010-06-30 17:58:25 +00:00
mControlParser.appendCode(mOutput.getCode());
2010-06-30 17:58:25 +00:00
return true;
}
/// \todo add an option to disable this nonsense
if (keyword == Scanner::K_endif)
{
// surplus endif
getErrorHandler().warning("endif without matching if/elseif", loc);
SkipParser skip(getErrorHandler(), getContext());
scanner.scan(skip);
return true;
}
if (keyword == Scanner::K_end && mEnd)
{
return false;
}
mLineParser.reset();
if (mLineParser.parseKeyword(keyword, loc, scanner))
scanner.scan(mLineParser);
return true;
}
bool ScriptParser::parseSpecial(int code, const TokenLoc& loc, Scanner& scanner)
{
if (code == Scanner::S_newline) // empty line
return true;
if (code == Scanner::S_open) /// \todo Option to switch this off
{
scanner.putbackSpecial(code, loc);
return parseKeyword(Scanner::K_if, loc, scanner);
}
mLineParser.reset();
if (mLineParser.parseSpecial(code, loc, scanner))
scanner.scan(mLineParser);
return true;
}
void ScriptParser::parseEOF(Scanner& scanner)
{
if (mEnd)
Parser::parseEOF(scanner);
}
void ScriptParser::reset()
{
mLineParser.reset();
mOutput.clear();
}
}