mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-30 01:45:38 +00:00
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
|
||||
lineparser literals locals output parser scanner scriptparser skipparser streamerrorhandler
|
||||
stringparser tokenloc nullerrorhandler opcodes extensions0 declarationparser
|
||||
quickfileparser discardparser
|
||||
quickfileparser discardparser junkparser
|
||||
)
|
||||
|
||||
add_component_dir (interpreter
|
||||
|
@ -123,7 +123,7 @@ if(QT_QTGUI_LIBRARY AND QT_QTCORE_LIBRARY)
|
|||
launchersettings
|
||||
settingsbase
|
||||
)
|
||||
|
||||
|
||||
add_component_qt_dir (process
|
||||
processinvoker
|
||||
)
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "extensions.hpp"
|
||||
#include "context.hpp"
|
||||
#include "discardparser.hpp"
|
||||
#include "junkparser.hpp"
|
||||
|
||||
namespace Compiler
|
||||
{
|
||||
|
@ -752,7 +753,7 @@ namespace Compiler
|
|||
}
|
||||
|
||||
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;
|
||||
int optionalCount = 0;
|
||||
|
@ -760,6 +761,7 @@ namespace Compiler
|
|||
ExprParser parser (getErrorHandler(), getContext(), mLocals, mLiterals, true);
|
||||
StringParser stringParser (getErrorHandler(), getContext(), mLiterals);
|
||||
DiscardParser discardParser (getErrorHandler(), getContext());
|
||||
JunkParser junkParser (getErrorHandler(), getContext(), ignoreKeyword);
|
||||
|
||||
std::stack<std::vector<Interpreter::Type_Code> > stack;
|
||||
|
||||
|
@ -815,6 +817,13 @@ namespace Compiler
|
|||
if (discardParser.isEmpty())
|
||||
break;
|
||||
}
|
||||
else if (*iter=='j')
|
||||
{
|
||||
/// \todo disable this when operating in strict mode
|
||||
junkParser.reset();
|
||||
|
||||
scanner.scan (junkParser);
|
||||
}
|
||||
else
|
||||
{
|
||||
parser.reset();
|
||||
|
|
|
@ -96,11 +96,12 @@ namespace Compiler
|
|||
/// \return Type ('l': integer, 'f': float)
|
||||
|
||||
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.
|
||||
/// \param arguments Uses ScriptArgs typedef
|
||||
/// \see Compiler::ScriptArgs
|
||||
/// \param invert Store arguments in reverted order.
|
||||
/// \param ignoreKeyword A keyword that is seen as junk
|
||||
/// \return number of optional arguments
|
||||
};
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ namespace Compiler
|
|||
x - Optional, ignored string argument
|
||||
X - Optional, ignored numeric expression
|
||||
z - Optional, ignored string or numeric argument
|
||||
j - A piece of junk (either . or a specific keyword)
|
||||
**/
|
||||
typedef std::string ScriptArgs;
|
||||
|
||||
|
|
|
@ -179,7 +179,7 @@ namespace Compiler
|
|||
extensions.registerInstruction ("setjournalindex", "cl", opcodeSetJournalIndex);
|
||||
extensions.registerFunction ("getjournalindex", 'l', "c", opcodeGetJournalIndex);
|
||||
extensions.registerInstruction ("addtopic", "S" , opcodeAddTopic);
|
||||
extensions.registerInstruction ("choice", "/SlSlSlSlSlSlSlSlSlSlSlSlSlSlSlSl", opcodeChoice);
|
||||
extensions.registerInstruction ("choice", "j/SlSlSlSlSlSlSlSlSlSlSlSlSlSlSlSl", opcodeChoice);
|
||||
extensions.registerInstruction("forcegreeting","",opcodeForceGreeting,
|
||||
opcodeForceGreetingExplicit);
|
||||
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()));
|
||||
|
||||
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());
|
||||
extensions->generateInstructionCode (keyword, mCode, mLiterals,
|
||||
mExplicit, optionals);
|
||||
|
|
Loading…
Reference in a new issue