added: possibility to define a block

changed: in Functions
         Functions are only for user-defined functions now
         (before they could remember a string variable too)
added:   class Vars for variables
         a variable can be a string or an alias to an other function or block
added:   now we can have nested functions calls e.g.:
         [function1 [function2]]
         in the above example an output (stream) from function2 will be passed
         as the first argument to funcion1 (will be passed as a string)
removed: UTF8() method from PatternParser
         now it is treated that when we have only std::string (or char*)
         that this is an UTF-8 string




git-svn-id: svn://ttmath.org/publicrep/ezc/trunk@970 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
2014-10-17 21:36:55 +00:00
parent b5faf171e3
commit 71c5bd11d5
15 changed files with 981 additions and 499 deletions

View File

@@ -48,10 +48,9 @@ namespace Ezc
PatternParser::PatternParser()
{
allow_include = true;
input_as_utf8 = true;
pblocks = 0;
include_level_max = 100;
delete_white_text_items = false;
include_level_max = 100;
}
@@ -116,6 +115,12 @@ void PatternParser::Directory(const std::wstring & dir, const std::wstring & dir
void PatternParser::SetBlocks(Blocks & blocks)
{
pblocks = &blocks;
}
void PatternParser::ParseFile(const std::string & file_name, Pattern & pattern)
{
ParseFile(file_name.c_str(), pattern);
@@ -156,11 +161,7 @@ void PatternParser::ParseFile(const wchar_t * file_name, Pattern & pattern)
void PatternParser::ParseString(const char * str, Pattern & pattern)
{
if( input_as_utf8 )
PT::UTF8ToWide(str, string_content);
else
AssignString(str, string_content);
PT::UTF8ToWide(str, string_content);
ParseString(string_content.c_str(), pattern);
string_content.clear();
}
@@ -218,16 +219,6 @@ void PatternParser::SetIncludeMax(int include_max)
void PatternParser::UTF8(bool utf8)
{
input_as_utf8 = utf8;
}
@@ -343,38 +334,13 @@ return true;
void PatternParser::ReadFile(std::ifstream & file, std::wstring & result)
{
if( input_as_utf8 )
{
PT::UTF8ToWide(file, result);
}
else
{
ReadFileContent(file, result);
}
PT::UTF8ToWide(file, result);
}
void PatternParser::ReadFileContent(std::ifstream & file, std::wstring & result)
{
while( true )
{
int c = file.get();
if( !file )
break;
result += static_cast<wchar_t>(c);
}
}
int PatternParser::ReadCharInText()
{
if( *itext==0 || *itext=='[' )
@@ -519,14 +485,38 @@ return true;
bool PatternParser::ReadParams(Item::Function & function)
{
function.params.clear();
while( true )
{
SkipWhite();
while( ReadString(temp_param) )
function.params.push_back(temp_param);
if( *itext == '[' )
{
++itext; // skipping '['
ReadFunction(function.AddNewParam());
temp_param.clear();
SkipWhite();
if( *itext == ']' )
++itext;
}
else
if( *itext == '\"' )
{
if( ReadString(temp_param) )
{
Item::Function & fun = function.AddNewParam();
fun.par = temp_param;
// fun.name is empty so it is treated as a text parameter
}
return !function.params.empty();
temp_param.clear();
}
else
{
break;
}
}
return !function.parameters.empty();
}
@@ -534,13 +524,14 @@ return !function.params.empty();
bool PatternParser::ReadFunction(Item::Function & function)
{
SkipWhite();
function.name.clear();
function.params.clear();
function.Clear();
if( !ReadName(function.name) )
return false;
if( IsPositiveNumber(function.name) )
function.arg = wcstol(function.name.c_str(), 0, 10);
ReadParams(function);
return true;
@@ -556,8 +547,7 @@ bool PatternParser::ReadFunctions(Item & item)
while( ReadFunction(temp_function) )
item.functions.push_back(temp_function);
temp_function.name.clear();
temp_function.params.clear();
temp_function.Clear();
return !item.functions.empty();
}
@@ -667,11 +657,25 @@ void PatternParser::ReadDirectiveIsno(Item & item)
void PatternParser::ReadDirectiveEnd(Item & item)
{
item.type = Item::item_end;
}
void PatternParser::ReadDirectiveElse(Item & item)
{
item.type = Item::item_else;
}
void PatternParser::ReadDirectiveIfindex(Item & item)
{
item.type = Item::item_err;
item.functions.clear();
temp_function.params.clear();
temp_function.Clear();
// reading: odd, even, first or a number (without quotes)
if( !ReadName(temp_function.name) )
@@ -724,24 +728,23 @@ void PatternParser::ReadDirectiveDef(Item & item)
item.type = Item::item_err;
ReadFunctions(item);
if( item.functions.size() == 1 )
if( item.functions.size() == 1 && item.functions[0].parameters.size() == 1 )
{
if( item.functions[0].params.size() == 1 )
{
// this is: [def variable "value"]
item.type = Item::item_def;
}
// it is [def name "value"]
// or [def name [otherfunction]]
// or [def name [otherfunction "argument"]] etc.
item.type = Item::item_def;
}
else
if( item.functions.size() == 2 )
if( item.functions.size() == 2 &&
item.functions[0].parameters.empty() && item.functions[1].parameters.empty() )
{
if( item.functions[0].params.empty() && item.functions[1].params.empty())
{
// this is:
// [def variable2 variable1], or
// [def function2 function1]
item.type = Item::item_def;
}
// it is an alias:
// [def name function]
// (name is an alias to a function, to a block or to an other variable)
item.type = Item::item_def;
}
}
@@ -762,14 +765,30 @@ void PatternParser::ReadDirectiveEzc(Item & item)
ReadFunctions(item);
}
void PatternParser::ReadDirectiveBlock(Item & item)
{
item.type = Item::item_block;
ReadFunctions(item);
// only one function without arguments
if( item.functions.size() != 1 || !item.functions[0].parameters.empty() )
item.type = Item::item_err;
}
// user defined directive
void PatternParser::ReadDirectiveNormal(const std::wstring & name, Item & item)
{
temp_function.name = name;
temp_function.Clear();
ReadParams(temp_function);
temp_function.name = name;
if( IsPositiveNumber(name) )
temp_function.arg = wcstol(name.c_str(), 0, 10);
item.functions.clear();
item.functions.push_back(temp_function);
item.type = Item::item_normal;
}
@@ -792,13 +811,14 @@ std::wstring name;
else if( name == L"if-index" ) ReadDirectiveIfindex(item);
else if( name == L"is" ) ReadDirectiveIs(item);
else if( name == L"is-no" ) ReadDirectiveIsno(item);
else if( name == L"end" ) item.type = Item::item_end;
else if( name == L"else" ) item.type = Item::item_else;
else if( name == L"end" ) ReadDirectiveEnd(item);
else if( name == L"else" ) ReadDirectiveElse(item);
else if( name == L"for" ) ReadDirectiveFor(item);
else if( name == L"include" ) ReadDirectiveInclude(item);
else if( name == L"def" ) ReadDirectiveDef(item);
else if( name == L"filter" ) ReadDirectiveFilter(item);
else if( name == L"ezc" ) ReadDirectiveEzc(item);
else if( name == L"block" ) ReadDirectiveBlock(item);
else if( name == L"#" ) ReadDirectiveComment(item);
else
ReadDirectiveNormal(name, item);
@@ -904,6 +924,21 @@ void PatternParser::CreateTreeReadIf(Item & item)
void PatternParser::CreateTreeReadBlock(Item & item)
{
Item item_block;
CreateTree(item_block);
if( item_block.LastItemType() == Item::item_end )
item_block.DeleteLastItem();
if( pblocks && item.functions.size()==1 )
pblocks->Insert(item.functions[0].name, item_block);
}
void PatternParser::CreateTreeReadFor(Item & item)
{
Item * pitem = item.AddItem();
@@ -931,8 +966,12 @@ void PatternParser::CreateTree(Item & item)
item.DeleteLastItem();
return;
}
if( pitem->type == Item::item_block )
CreateTreeReadBlock(*pitem);
}
while( pitem->type == Item::item_comment );
while( pitem->type == Item::item_comment ||
pitem->type == Item::item_block );
if( pitem->type == Item::item_end || pitem->type == Item::item_else )
return;
@@ -954,6 +993,8 @@ void PatternParser::CreateTree(Item & item)
if( pitem->type == Item::item_include )
CreateTreeReadInclude(*pitem);
// item_def is ignored here
}
}