handle junk in argument lists (Fixes #2206)

moveref
Marc Zinnschlag 10 years ago
parent 5cb94da9c5
commit b951251572

@ -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
@ -123,7 +123,7 @@ if(QT_QTGUI_LIBRARY AND QT_QTCORE_LIBRARY)
launchersettings launchersettings
settingsbase settingsbase
) )
add_component_qt_dir (process add_component_qt_dir (process
processinvoker processinvoker
) )

@ -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);

@ -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;
}

@ -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…
Cancel
Save