Fix parser error when using new-lines in dictionaries

fixes #10204
This commit is contained in:
Gunnar Beutner 2015-09-23 16:37:21 +02:00
parent 84536da221
commit e19a36c659
5 changed files with 17 additions and 5 deletions

View File

@ -240,9 +240,9 @@ in return T_IN;
\> return T_GREATER_THAN; \> return T_GREATER_THAN;
} }
\( { yyextra->m_IgnoreNewlines++; return '('; } \( { yyextra->m_IgnoreNewlines.push(true); return '('; }
\) { yyextra->m_IgnoreNewlines--; return ')'; } \) { yyextra->m_IgnoreNewlines.pop(); return ')'; }
[\r\n]+ { yycolumn -= strlen(yytext) - 1; if (!yyextra->m_IgnoreNewlines) { return T_NEWLINE; } } [\r\n]+ { yycolumn -= strlen(yytext) - 1; if (!yyextra->m_IgnoreNewlines.top()) { return T_NEWLINE; } }
<<EOF>> { if (!yyextra->m_Eof) { yyextra->m_Eof = true; return T_NEWLINE; } else { yyterminate(); } } <<EOF>> { if (!yyextra->m_Eof) { yyextra->m_Eof = true; return T_NEWLINE; } else { yyterminate(); } }
. return yytext[0]; . return yytext[0];

View File

@ -240,9 +240,13 @@ Expression *ConfigCompiler::Compile(void)
//yydebug = 1; //yydebug = 1;
m_IgnoreNewlines.push(false);
if (yyparse(&llist, this) != 0) if (yyparse(&llist, this) != 0)
return NULL; return NULL;
m_IgnoreNewlines.pop();
std::vector<Expression *> dlist; std::vector<Expression *> dlist;
typedef std::pair<Expression *, EItemInfo> EListItem; typedef std::pair<Expression *, EItemInfo> EListItem;
int num = 0; int num = 0;
@ -612,11 +616,13 @@ rterm_array: '['
rterm_scope_require_side_effect: '{' rterm_scope_require_side_effect: '{'
{ {
context->m_IgnoreNewlines.push(false);
context->m_OpenBraces++; context->m_OpenBraces++;
} }
statements '}' statements '}'
{ {
context->m_OpenBraces--; context->m_OpenBraces--;
context->m_IgnoreNewlines.pop();
std::vector<Expression *> dlist; std::vector<Expression *> dlist;
typedef std::pair<Expression *, EItemInfo> EListItem; typedef std::pair<Expression *, EItemInfo> EListItem;
int num = 0; int num = 0;
@ -633,11 +639,13 @@ rterm_scope_require_side_effect: '{'
rterm_scope: '{' rterm_scope: '{'
{ {
context->m_IgnoreNewlines.push(false);
context->m_OpenBraces++; context->m_OpenBraces++;
} }
statements '}' statements '}'
{ {
context->m_OpenBraces--; context->m_OpenBraces--;
context->m_IgnoreNewlines.pop();
std::vector<Expression *> dlist; std::vector<Expression *> dlist;
typedef std::pair<Expression *, EItemInfo> EListItem; typedef std::pair<Expression *, EItemInfo> EListItem;
int num = 0; int num = 0;

View File

@ -44,7 +44,7 @@ std::map<String, std::vector<ZoneFragment> > ConfigCompiler::m_ZoneDirs;
ConfigCompiler::ConfigCompiler(const String& path, std::istream *input, ConfigCompiler::ConfigCompiler(const String& path, std::istream *input,
const String& zone, const String& package) const String& zone, const String& package)
: m_Path(path), m_Input(input), m_Zone(zone), m_Package(package), : m_Path(path), m_Input(input), m_Zone(zone), m_Package(package),
m_Eof(false), m_OpenBraces(0), m_IgnoreNewlines(0) m_Eof(false), m_OpenBraces(0)
{ {
InitializeScanner(); InitializeScanner();
} }

View File

@ -141,10 +141,10 @@ public:
bool m_Eof; bool m_Eof;
int m_OpenBraces; int m_OpenBraces;
int m_IgnoreNewlines;
std::ostringstream m_LexBuffer; std::ostringstream m_LexBuffer;
CompilerDebugInfo m_LocationBegin; CompilerDebugInfo m_LocationBegin;
std::stack<bool> m_IgnoreNewlines;
std::stack<bool> m_Apply; std::stack<bool> m_Apply;
std::stack<bool> m_ObjectAssign; std::stack<bool> m_ObjectAssign;
std::stack<bool> m_SeenAssign; std::stack<bool> m_SeenAssign;

View File

@ -204,6 +204,10 @@ BOOST_AUTO_TEST_CASE(simple)
expr = ConfigCompiler::CompileText("<test>", "\"\\'test\""); expr = ConfigCompiler::CompileText("<test>", "\"\\'test\"");
BOOST_CHECK_THROW(expr->Evaluate(frame).GetValue(), ScriptError); BOOST_CHECK_THROW(expr->Evaluate(frame).GetValue(), ScriptError);
delete expr; delete expr;
expr = ConfigCompiler::CompileText("<test>", "({ a = 3\nb = 3 })");
BOOST_CHECK(expr->Evaluate(frame).GetValue().IsObjectType<Dictionary>());
delete expr;
} }
BOOST_AUTO_TEST_CASE(advanced) BOOST_AUTO_TEST_CASE(advanced)