1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-01-05 15:55:45 +00:00
OpenMW/components/compiler/fileparser.cpp

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

142 lines
4.0 KiB
C++
Raw Normal View History

2010-06-27 17:20:21 +00:00
#include "fileparser.hpp"
#include "scanner.hpp"
2022-09-22 18:26:05 +00:00
#include "tokenloc.hpp"
2010-06-27 17:20:21 +00:00
namespace Compiler
{
2022-09-22 18:26:05 +00:00
FileParser::FileParser(ErrorHandler& errorHandler, Context& context)
: Parser(errorHandler, context)
, mScriptParser(errorHandler, context, mLocals, true)
, mState(BeginState)
{
}
2010-06-27 17:20:21 +00:00
std::string FileParser::getName() const
2010-06-27 17:20:21 +00:00
{
return mName;
2010-06-27 17:20:21 +00:00
}
2010-08-22 10:47:56 +00:00
2022-09-22 18:26:05 +00:00
void FileParser::getCode(std::vector<Interpreter::Type_Code>& code) const
{
2022-09-22 18:26:05 +00:00
mScriptParser.getCode(code);
}
2010-08-22 10:47:56 +00:00
const Locals& FileParser::getLocals() const
{
return mLocals;
}
2010-06-27 17:20:21 +00:00
2022-09-22 18:26:05 +00:00
bool FileParser::parseName(const std::string& name, const TokenLoc& loc, Scanner& scanner)
2010-06-27 17:20:21 +00:00
{
2022-09-22 18:26:05 +00:00
if (mState == NameState)
{
mName = name;
mState = BeginCompleteState;
return true;
}
2010-08-22 10:47:56 +00:00
2022-09-22 18:26:05 +00:00
if (mState == EndNameState)
{
// optional repeated name after end statement
2022-09-22 18:26:05 +00:00
if (mName != name)
reportWarning("Names for script " + mName + " do not match", loc);
2010-08-22 10:47:56 +00:00
mState = EndCompleteState;
return false; // we are stopping here, because there might be more garbage on the end line,
// that we must ignore.
//
/// \todo allow this workaround to be disabled for newer scripts
}
2010-08-22 10:47:56 +00:00
2022-09-22 18:26:05 +00:00
if (mState == BeginCompleteState)
{
2022-09-22 18:26:05 +00:00
reportWarning("Stray string (" + name + ") after begin statement", loc);
return true;
}
2022-09-22 18:26:05 +00:00
return Parser::parseName(name, loc, scanner);
2010-06-27 17:20:21 +00:00
}
2022-09-22 18:26:05 +00:00
bool FileParser::parseKeyword(int keyword, const TokenLoc& loc, Scanner& scanner)
2010-06-27 17:20:21 +00:00
{
2022-09-22 18:26:05 +00:00
if (mState == BeginState && keyword == Scanner::K_begin)
{
mState = NameState;
scanner.enableTolerantNames(); /// \todo disable
return true;
}
2010-08-22 10:47:56 +00:00
2022-09-22 18:26:05 +00:00
if (mState == NameState)
{
// keywords can be used as script names too. Thank you Morrowind for another
// syntactic perversity :(
mName = loc.mLiteral;
mState = BeginCompleteState;
return true;
}
2010-08-22 10:47:56 +00:00
2022-09-22 18:26:05 +00:00
if (mState == EndNameState)
{
// optional repeated name after end statement
2022-09-22 18:26:05 +00:00
if (mName != loc.mLiteral)
reportWarning("Names for script " + mName + " do not match", loc);
mState = EndCompleteState;
return false; // we are stopping here, because there might be more garbage on the end line,
// that we must ignore.
//
/// \todo allow this workaround to be disabled for newer scripts
}
2022-09-22 18:26:05 +00:00
return Parser::parseKeyword(keyword, loc, scanner);
2010-06-27 17:20:21 +00:00
}
2022-09-22 18:26:05 +00:00
bool FileParser::parseSpecial(int code, const TokenLoc& loc, Scanner& scanner)
2010-06-27 17:20:21 +00:00
{
// Ignore any junk special characters
if (mState == BeginState)
{
if (code != Scanner::S_newline)
2022-09-22 18:26:05 +00:00
reportWarning("Stray special character before begin statement", loc);
return true;
}
2010-08-22 10:47:56 +00:00
2022-09-22 18:26:05 +00:00
if (code == Scanner::S_newline)
{
2022-09-22 18:26:05 +00:00
if (mState == BeginCompleteState)
{
// parse the script body
mScriptParser.reset();
2010-08-22 10:47:56 +00:00
2022-09-22 18:26:05 +00:00
scanner.scan(mScriptParser);
2010-08-22 10:47:56 +00:00
mState = EndNameState;
return true;
}
2010-08-22 10:47:56 +00:00
2022-09-22 18:26:05 +00:00
if (mState == EndCompleteState || mState == EndNameState)
{
// we are done here -> ignore the rest of the script
return false;
}
}
2010-08-22 10:47:56 +00:00
2022-09-22 18:26:05 +00:00
return Parser::parseSpecial(code, loc, scanner);
2010-06-27 17:20:21 +00:00
}
2022-09-22 18:26:05 +00:00
void FileParser::parseEOF(Scanner& scanner)
2010-06-27 17:20:21 +00:00
{
2022-09-22 18:26:05 +00:00
if (mState != EndNameState && mState != EndCompleteState)
Parser::parseEOF(scanner);
}
2010-08-22 10:47:56 +00:00
void FileParser::reset()
{
mState = BeginState;
mName.clear();
mScriptParser.reset();
2010-08-22 10:47:56 +00:00
Parser::reset();
2010-06-27 17:20:21 +00:00
}
}