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

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