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:
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user