changed: in PatternParser: the way how nested ezc funcions are parsed

now we can have: [fun] [[fun]] or even [[[fun]]]
         also when using keywords: [if fun] [if [fun]] or [if [[[[fun]]]]]




git-svn-id: svn://ttmath.org/publicrep/ezc/trunk@1041 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
Tomasz Sowa 2016-08-25 13:11:33 +00:00
parent 363605bde5
commit eace4d41cc
2 changed files with 72 additions and 79 deletions

View File

@ -559,32 +559,6 @@ bool PatternParser::ReadString(std::wstring & str)
bool PatternParser::ReadNestedFunction(Item::Function & function)
{
++itext; // skipping '['
bool res = ReadFunction(function.AddNewParam(), true);
if( !res )
{
SkipOneStatement();
return false;
}
SkipWhite();
if( *itext == ']' )
{
++itext;
return true;
}
else
{
SkipOneStatement();
return false;
}
}
bool PatternParser::ReadParamString(Item::Function & function) bool PatternParser::ReadParamString(Item::Function & function)
{ {
@ -600,15 +574,16 @@ return ReadString(fun.name);
*/ */
bool PatternParser::ReadParams(Item::Function & function) bool PatternParser::ReadParams(Item::Function & function)
{ {
bool res; bool res = true;
bool check_next_param = true;
do while( check_next_param && res )
{ {
SkipWhite(); SkipWhite();
if( *itext == '[' ) if( *itext == '[' )
{ {
res = ReadNestedFunction(function); res = ReadFunction(function.AddNewParam(), true);
} }
else else
if( *itext == '\"' ) if( *itext == '\"' )
@ -623,73 +598,86 @@ bool res;
else else
{ {
// *itext is equal to ']' // *itext is equal to ']'
check_next_param = false;
res = true; res = true;
break;
} }
} }
while( res );
return res; return res;
} }
/*
returns true if it correctly reads all parameters
*/ bool PatternParser::ReadFunction(Item::Function & function, bool with_params)
bool PatternParser::ReadFunction(Item::Function & function, bool with_params, const std::wstring * function_name)
{ {
bool res = false;
SkipWhite(); SkipWhite();
function.Clear(); function.Clear();
function.is_function = true;
if( function_name ) if( *itext == '[' )
{
function.name = *function_name;
}
else
if( !ReadName(function.name) )
return false;
if( *itext == ':' )
{ {
itext += 1; itext += 1;
ReadName(function.postfix); // we allow the postfix to be empty res = ReadFunction(function, true);
}
CheckFunctionIsNumber(function); SkipWhite();
if( with_params ) if( *itext == ']' )
return ReadParams(function); {
itext += 1;
return true; }
} else
{
SkipOneStatement();
/* res = false;
returns true if it correctly reads all parameters }
*/
bool PatternParser::ReadFunction(Item & item)
{
SkipWhite();
if( *itext == ']' )
{
item.has_function = false;
} }
else else
{ {
item.has_function = true; res = ReadName(function.name);
if( !ReadFunction(item.function, true) ) if( res )
{ {
item.function.Clear(); if( *itext == ':' )
item.type = Item::item_err; {
return false; itext += 1;
ReadName(function.postfix); // we allow the postfix to be empty
}
if( with_params )
res = ReadParams(function);
} }
} }
return true; if( res )
{
// IMPROVE ME
// this will be called more than once for nested functions
CheckFunctionIsNumber(function);
}
function.is_function = res;
return res;
}
/*
returns true if a function has been correctly read
*/
bool PatternParser::ReadFunction(Item & item)
{
bool function_read_correctly = ReadFunction(item.function, true);
if( !function_read_correctly )
{
item.function.Clear();
item.type = Item::item_err;
}
return function_read_correctly;
} }
@ -711,13 +699,14 @@ void PatternParser::CreateTreeReadItemDirectiveCheckEnding(Item & item)
} }
// user defined directive
void PatternParser::ReadDirectiveNormal(const std::wstring & name, Item & item)
void PatternParser::ReadNormalStatement(Item & item)
{ {
item.type = Item::item_function; item.type = Item::item_function;
item.has_function = true; item.has_function = true;
if( !ReadFunction(item.function, true, &name) ) if( !ReadFunction(item.function, true) )
{ {
item.type = Item::item_err; item.type = Item::item_err;
item.function.Clear(); item.function.Clear();
@ -734,7 +723,6 @@ void PatternParser::ReadDirectiveIf(Item & item)
void PatternParser::ReadDirectiveEnd(Item & item) void PatternParser::ReadDirectiveEnd(Item & item)
{ {
item.type = Item::item_end; item.type = Item::item_end;
@ -846,6 +834,8 @@ std::wstring name;
++itext; ++itext;
SkipWhite(); SkipWhite();
const wchar_t * old_itext = itext;
ReadName(name); ReadName(name);
if ( name == L"if" ) ReadDirectiveIf(item); if ( name == L"if" ) ReadDirectiveIf(item);
@ -860,7 +850,11 @@ std::wstring name;
else if( name == L"block" ) ReadDirectiveBlock(item); else if( name == L"block" ) ReadDirectiveBlock(item);
else if( name == L"return" ) ReadDirectiveReturn(item); else if( name == L"return" ) ReadDirectiveReturn(item);
else if( name == L"#" ) ReadDirectiveComment(item); else if( name == L"#" ) ReadDirectiveComment(item);
else if( !name.empty() ) ReadDirectiveNormal(name, item); else if( *old_itext == '[' || !name.empty() )
{
itext = old_itext;
ReadNormalStatement(item);
}
CreateTreeReadItemDirectiveCheckEnding(item); CreateTreeReadItemDirectiveCheckEnding(item);
} }

View File

@ -154,10 +154,9 @@ private:
bool ReadName(std::wstring & name); bool ReadName(std::wstring & name);
bool ReadFunctionName(std::wstring & name, std::wstring & postfix); bool ReadFunctionName(std::wstring & name, std::wstring & postfix);
bool ReadString(std::wstring & str); bool ReadString(std::wstring & str);
bool ReadNestedFunction(Item::Function & function);
bool ReadParamString(Item::Function & function); bool ReadParamString(Item::Function & function);
bool ReadParams(Item::Function & function); bool ReadParams(Item::Function & function);
bool ReadFunction(Item::Function & function, bool with_params, const std::wstring * function_name = 0); bool ReadFunction(Item::Function & function, bool with_params);
bool ReadFunction(Item & item); bool ReadFunction(Item & item);
void ReadDirectiveIf(Item & item); void ReadDirectiveIf(Item & item);
@ -172,7 +171,7 @@ private:
void ReadDirectiveOut(Item & item); void ReadDirectiveOut(Item & item);
void ReadDirectiveBlock(Item & item); void ReadDirectiveBlock(Item & item);
void ReadDirectiveReturn(Item & item); void ReadDirectiveReturn(Item & item);
void ReadDirectiveNormal(const std::wstring & name, Item & item); void ReadNormalStatement(Item & item);
void CreateTreeReadItemDirectiveCheckEnding(Item & item); void CreateTreeReadItemDirectiveCheckEnding(Item & item);
void CreateTreeReadItemDirective(Item & item); void CreateTreeReadItemDirective(Item & item);