编辑:现在修复代码
我敢肯定一些更干净的版本是可能的,但它可以完成任务:
Class CMetaStringToTagGroup
{
// Find next string bracketed by " in input string, starting search
// at given index. Returns string and end-position of search
string FindNextKeyName( object self, string input, number & searchPos )
{
number totalLength = len( input )
number start = 0, end = 0
while( searchPos < totalLength )
{
searchpos++
if ( "\"" == input.mid(searchpos-1,1) )
{
if ( !start )
start = searchpos-1
else
{
end = searchpos-1
return input.mid(start+1,end-start-1)
}
}
}
return ""
}
// Returns the next of either "{" , "}" or """ after a collon ":"
string GetNextIndicator( object self, string input, number & searchPos )
{
number totalLength = len( input )
while( searchPos < totalLength )
{
searchpos++
if ( "{" == input.mid(searchpos-1,1) )
return "{"
if ( "}" == input.mid(searchpos-1,1) )
return "}"
if ( "\"" == input.mid(searchpos-1,1) )
return "\""
}
return ""
}
// In a tag-path string, find location of last colon
number findLastColon( object self, string input )
{
number totalLength = len( input )
number lastPos = -1
number searchPos = 0
while( searchPos < totalLength )
{
searchpos++
if ( ":" == input.mid(searchpos-1,1) )
lastPos = searchpos-1
}
return lastPos
}
// Parse textstring and create taggroup from it
TagGroup CreateTagFromText( object self, string input )
{
TagGroup rootTG = NewTagGroup()
string currentPath = ""
number totalLength = len( input )
number searchPos = 0
number searchPos2
string keyName, indicator
while( searchPos < totalLength )
{
// search for new key or closing bracket, whatever first
searchPos2 = searchPos
indicator = self.GetNextIndicator( input, searchPos2 )
keyName = self.FindNextKeyName( input, searchPos )
if ( ( "}" == indicator ) && (searchpos2<searchPos ) )
{
// decrease hierachy
number cutPos = self.findLastColon( currentPath )
currentPath = left( currentPath, cutPos )
result("\n DEC ")
searchPos = searchPos2
}
else
{
// Either add value or new sub-tagGroup
if ( "" == keyname ) break; // No more keys found
indicator = self.GetNextIndicator( input, searchPos )
if ( "" == indicator ) break; // No more indicator found -- should not happen!
if ( "{" == indicator )
{
// increase hierachy
currentPath += ":" + keyname
rootTg.TagGroupSetTagAsTagGroup( currentPath, NewTagGroup() )
result("\n INC ("+keyname+")")
}
else if ( "\"" == indicator )
{
// Add value
searchPos--
string valStr = self.FindNextKeyName( input, searchPos )
rootTg.TagGroupSetTagAsString( currentPath + ":" + keyname, valStr )
result("\n VAL("+keyname+") ")
}
}
}
return rootTg
}
}
{
// Reading input text
number fileID = OpenFileForReading("C:\\test.txt")
object fStream = NewStreamFromFileReference(fileID,1)
string inputStr = fStream.StreamReadAsText(0, fStream.StreamGetSize())
// Parsing text
number searchPos = 0
TagGroup con = alloc(CMetaStringToTagGroup).CreateTagFromText( inputStr )
con.TagGroupopenBrowserwindow("",0)
}