forked from mirror/openmw-tes3mp
handle junk in argument lists (Fixes #2206)
This commit is contained in:
parent
5cb94da9c5
commit
b951251572
8 changed files with 106 additions and 6 deletions
|
@ -70,7 +70,7 @@ add_component_dir (compiler
|
||||||
context controlparser errorhandler exception exprparser extensions fileparser generator
|
context controlparser errorhandler exception exprparser extensions fileparser generator
|
||||||
lineparser literals locals output parser scanner scriptparser skipparser streamerrorhandler
|
lineparser literals locals output parser scanner scriptparser skipparser streamerrorhandler
|
||||||
stringparser tokenloc nullerrorhandler opcodes extensions0 declarationparser
|
stringparser tokenloc nullerrorhandler opcodes extensions0 declarationparser
|
||||||
quickfileparser discardparser
|
quickfileparser discardparser junkparser
|
||||||
)
|
)
|
||||||
|
|
||||||
add_component_dir (interpreter
|
add_component_dir (interpreter
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include "extensions.hpp"
|
#include "extensions.hpp"
|
||||||
#include "context.hpp"
|
#include "context.hpp"
|
||||||
#include "discardparser.hpp"
|
#include "discardparser.hpp"
|
||||||
|
#include "junkparser.hpp"
|
||||||
|
|
||||||
namespace Compiler
|
namespace Compiler
|
||||||
{
|
{
|
||||||
|
@ -752,7 +753,7 @@ namespace Compiler
|
||||||
}
|
}
|
||||||
|
|
||||||
int ExprParser::parseArguments (const std::string& arguments, Scanner& scanner,
|
int ExprParser::parseArguments (const std::string& arguments, Scanner& scanner,
|
||||||
std::vector<Interpreter::Type_Code>& code)
|
std::vector<Interpreter::Type_Code>& code, int ignoreKeyword)
|
||||||
{
|
{
|
||||||
bool optional = false;
|
bool optional = false;
|
||||||
int optionalCount = 0;
|
int optionalCount = 0;
|
||||||
|
@ -760,6 +761,7 @@ namespace Compiler
|
||||||
ExprParser parser (getErrorHandler(), getContext(), mLocals, mLiterals, true);
|
ExprParser parser (getErrorHandler(), getContext(), mLocals, mLiterals, true);
|
||||||
StringParser stringParser (getErrorHandler(), getContext(), mLiterals);
|
StringParser stringParser (getErrorHandler(), getContext(), mLiterals);
|
||||||
DiscardParser discardParser (getErrorHandler(), getContext());
|
DiscardParser discardParser (getErrorHandler(), getContext());
|
||||||
|
JunkParser junkParser (getErrorHandler(), getContext(), ignoreKeyword);
|
||||||
|
|
||||||
std::stack<std::vector<Interpreter::Type_Code> > stack;
|
std::stack<std::vector<Interpreter::Type_Code> > stack;
|
||||||
|
|
||||||
|
@ -815,6 +817,13 @@ namespace Compiler
|
||||||
if (discardParser.isEmpty())
|
if (discardParser.isEmpty())
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
else if (*iter=='j')
|
||||||
|
{
|
||||||
|
/// \todo disable this when operating in strict mode
|
||||||
|
junkParser.reset();
|
||||||
|
|
||||||
|
scanner.scan (junkParser);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
parser.reset();
|
parser.reset();
|
||||||
|
|
|
@ -96,11 +96,12 @@ namespace Compiler
|
||||||
/// \return Type ('l': integer, 'f': float)
|
/// \return Type ('l': integer, 'f': float)
|
||||||
|
|
||||||
int parseArguments (const std::string& arguments, Scanner& scanner,
|
int parseArguments (const std::string& arguments, Scanner& scanner,
|
||||||
std::vector<Interpreter::Type_Code>& code);
|
std::vector<Interpreter::Type_Code>& code, int ignoreKeyword = -1);
|
||||||
///< Parse sequence of arguments specified by \a arguments.
|
///< Parse sequence of arguments specified by \a arguments.
|
||||||
/// \param arguments Uses ScriptArgs typedef
|
/// \param arguments Uses ScriptArgs typedef
|
||||||
/// \see Compiler::ScriptArgs
|
/// \see Compiler::ScriptArgs
|
||||||
/// \param invert Store arguments in reverted order.
|
/// \param invert Store arguments in reverted order.
|
||||||
|
/// \param ignoreKeyword A keyword that is seen as junk
|
||||||
/// \return number of optional arguments
|
/// \return number of optional arguments
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ namespace Compiler
|
||||||
x - Optional, ignored string argument
|
x - Optional, ignored string argument
|
||||||
X - Optional, ignored numeric expression
|
X - Optional, ignored numeric expression
|
||||||
z - Optional, ignored string or numeric argument
|
z - Optional, ignored string or numeric argument
|
||||||
|
j - A piece of junk (either . or a specific keyword)
|
||||||
**/
|
**/
|
||||||
typedef std::string ScriptArgs;
|
typedef std::string ScriptArgs;
|
||||||
|
|
||||||
|
|
|
@ -179,7 +179,7 @@ namespace Compiler
|
||||||
extensions.registerInstruction ("setjournalindex", "cl", opcodeSetJournalIndex);
|
extensions.registerInstruction ("setjournalindex", "cl", opcodeSetJournalIndex);
|
||||||
extensions.registerFunction ("getjournalindex", 'l', "c", opcodeGetJournalIndex);
|
extensions.registerFunction ("getjournalindex", 'l', "c", opcodeGetJournalIndex);
|
||||||
extensions.registerInstruction ("addtopic", "S" , opcodeAddTopic);
|
extensions.registerInstruction ("addtopic", "S" , opcodeAddTopic);
|
||||||
extensions.registerInstruction ("choice", "/SlSlSlSlSlSlSlSlSlSlSlSlSlSlSlSl", opcodeChoice);
|
extensions.registerInstruction ("choice", "j/SlSlSlSlSlSlSlSlSlSlSlSlSlSlSlSl", opcodeChoice);
|
||||||
extensions.registerInstruction("forcegreeting","",opcodeForceGreeting,
|
extensions.registerInstruction("forcegreeting","",opcodeForceGreeting,
|
||||||
opcodeForceGreetingExplicit);
|
opcodeForceGreetingExplicit);
|
||||||
extensions.registerInstruction("goodbye", "", opcodeGoodbye);
|
extensions.registerInstruction("goodbye", "", opcodeGoodbye);
|
||||||
|
|
48
components/compiler/junkparser.cpp
Normal file
48
components/compiler/junkparser.cpp
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
|
||||||
|
#include "junkparser.hpp"
|
||||||
|
|
||||||
|
#include "scanner.hpp"
|
||||||
|
|
||||||
|
Compiler::JunkParser::JunkParser (ErrorHandler& errorHandler, const Context& context,
|
||||||
|
int ignoreKeyword)
|
||||||
|
: Parser (errorHandler, context), mIgnoreKeyword (ignoreKeyword)
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool Compiler::JunkParser::parseInt (int value, const TokenLoc& loc, Scanner& scanner)
|
||||||
|
{
|
||||||
|
scanner.putbackInt (value, loc);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Compiler::JunkParser::parseFloat (float value, const TokenLoc& loc, Scanner& scanner)
|
||||||
|
{
|
||||||
|
scanner.putbackFloat (value, loc);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Compiler::JunkParser::parseName (const std::string& name, const TokenLoc& loc,
|
||||||
|
Scanner& scanner)
|
||||||
|
{
|
||||||
|
scanner.putbackName (name, loc);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Compiler::JunkParser::parseKeyword (int keyword, const TokenLoc& loc, Scanner& scanner)
|
||||||
|
{
|
||||||
|
if (keyword==mIgnoreKeyword)
|
||||||
|
reportWarning ("found junk (ignoring it)", loc);
|
||||||
|
else
|
||||||
|
scanner.putbackKeyword (keyword, loc);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Compiler::JunkParser::parseSpecial (int code, const TokenLoc& loc, Scanner& scanner)
|
||||||
|
{
|
||||||
|
if (code==Scanner::S_member)
|
||||||
|
reportWarning ("found junk (ignoring it)", loc);
|
||||||
|
else
|
||||||
|
scanner.putbackSpecial (code, loc);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
41
components/compiler/junkparser.hpp
Normal file
41
components/compiler/junkparser.hpp
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
#ifndef COMPILER_JUNKPARSER_H_INCLUDED
|
||||||
|
#define COMPILER_JUNKPARSER_H_INCLUDED
|
||||||
|
|
||||||
|
#include "parser.hpp"
|
||||||
|
|
||||||
|
namespace Compiler
|
||||||
|
{
|
||||||
|
/// \brief Parse an optional single junk token
|
||||||
|
class JunkParser : public Parser
|
||||||
|
{
|
||||||
|
int mIgnoreKeyword;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
JunkParser (ErrorHandler& errorHandler, const Context& context,
|
||||||
|
int ignoreKeyword = -1);
|
||||||
|
|
||||||
|
virtual bool parseInt (int value, const TokenLoc& loc, Scanner& scanner);
|
||||||
|
///< Handle an int token.
|
||||||
|
/// \return fetch another token?
|
||||||
|
|
||||||
|
virtual bool parseFloat (float value, const TokenLoc& loc, Scanner& scanner);
|
||||||
|
///< Handle a float token.
|
||||||
|
/// \return fetch another token?
|
||||||
|
|
||||||
|
virtual bool parseName (const std::string& name, const TokenLoc& loc,
|
||||||
|
Scanner& scanner);
|
||||||
|
///< Handle a name token.
|
||||||
|
/// \return fetch another token?
|
||||||
|
|
||||||
|
virtual bool parseKeyword (int keyword, const TokenLoc& loc, Scanner& scanner);
|
||||||
|
///< Handle a keyword token.
|
||||||
|
/// \return fetch another token?
|
||||||
|
|
||||||
|
virtual bool parseSpecial (int code, const TokenLoc& loc, Scanner& scanner);
|
||||||
|
///< Handle a special character token.
|
||||||
|
/// \return fetch another token?
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -304,7 +304,7 @@ namespace Compiler
|
||||||
errorDowngrade.reset (new ErrorDowngrade (getErrorHandler()));
|
errorDowngrade.reset (new ErrorDowngrade (getErrorHandler()));
|
||||||
|
|
||||||
std::vector<Interpreter::Type_Code> code;
|
std::vector<Interpreter::Type_Code> code;
|
||||||
int optionals = mExprParser.parseArguments (argumentType, scanner, code);
|
int optionals = mExprParser.parseArguments (argumentType, scanner, code, keyword);
|
||||||
mCode.insert (mCode.end(), code.begin(), code.end());
|
mCode.insert (mCode.end(), code.begin(), code.end());
|
||||||
extensions->generateInstructionCode (keyword, mCode, mLiterals,
|
extensions->generateInstructionCode (keyword, mCode, mLiterals,
|
||||||
mExplicit, optionals);
|
mExplicit, optionals);
|
||||||
|
|
Loading…
Reference in a new issue