Custom ResourceManager and ScriptTranslator

smiley80

02-03-2009 18:31:27

I'm currently working on porting Caelum to C#.
Caelum has the ability to read its configuration from script files, and so it creates its own resource manager and script translator.
It seems that it's not possible to create those in Mogre. Or have I overlooked something?

For the former it's fairly easy to create a workaround, the latter would require some jumping through hoops (or stealing code from Axiom).

Beauty

02-03-2009 22:59:39

What exactly should not be possible?
For parsing scripts Regular Expressions can help like a magic hand.

The Regex Coach is a really helpful tool do test and develop complex search pattern.
http://weitz.de/regex-coach

Maybe creating a wrapper would be lesser work?
(especially for updates)

smiley80

03-03-2009 00:01:00

What exactly should not be possible?

Creating classes which inherit from ResourceManager/ScriptTranslator.

For parsing scripts Regular Expressions can help like a magic hand.

The Regex Coach is a really helpful tool do test and develop complex search pattern.
http://weitz.de/regex-coach

Yeah, that could be an option. Haven't thought about using regexes, because I avoid thinking about them, they make my head hurt :wink: .


Maybe creating a wrapper would be lesser work?
(especially for updates)

Caelum isn't very large, and diffing the code wouldn't be that much work.

Beauty

12-03-2009 14:45:52

Just some lines of code for this beautiful add-on? Nice!

I can help you with RegEx.
If you tell me the concrete tasks, I can do this part.
Can you show me one or more example config files?
Is there a documentation how to store information in it?

What's about of using a public SVN for the Caelum port?

smiley80

12-03-2009 18:31:19

Just some lines of code for this beautiful add-on? Nice!
13280 lines so far (okay, ~9000 of them are the star catalogue :D ).

ATM I'm compiling against Axiom instead of Mogre, so I can realize the script stuff faster and start debugging the real stuff.
When that's completed I convert it back to Mogre (mainly a find+replace orgy).

Can you show me one or more example config files?
http://caelum.svn.sourceforge.net/viewv ... iew=markup

Is there a documentation how to store information in it?
My reference on that is how Caelum reads the scripts:
http://caelum.svn.sourceforge.net/viewv ... iew=markup
http://caelum.svn.sourceforge.net/viewv ... iew=markup

Beauty

12-03-2009 23:50:32

Oh, you are optimistic with just 13k lines :lol:

I think I can write a parser class for this files.
Reading and writing and syntax check (with concrete error message).
Regular expressions are great for file ripping, I learned it in my time of Perl programming!

By the way - the stucture looks similar to XML files, just with an other block definition.
If the author of Caelum would had used XML files instead, it would be easy to check for right syntax and values by XML Schemas (XSD files). Also it would be easy to import / export the settings with only a few lines of code (really few).
Well, maybe I'm spoiled by fine .NET classes and additionally the [serialize] option for classes :wink:

We need to determine
* where to store the read values
* where to write errors (to a logfile?)
* what to do if errors (use default values or abort) - how it will be handled by Caelum?
* does all values needs to be in the config file or are there optional ones?

smiley80

13-03-2009 08:24:08

I've thought about the following:

Step 1 - read all .os scripts and merge them:
This will happen automatically on startup.

Systems in the scripts can be declared abstract and can inherit from other systems:
abstract caelum_sky_system MyBaseSystem
{
julian_day 2451545.0

point_starfield {
mag0_pixel_size 16
min_pixel_size 4
max_pixel_size 6
}
}
caelum_sky_system MySystem: MyBaseSystem
{
point_starfield {
min_pixel_size 5
max_pixel_size 7
}
}


-iterate through all systems

  1. -if they are abstract save them in a temporary Dictionary<string, string> (key is the system's name, value is the script text)
    -if they are not abstract save them in a Dictionary<string, string>, which will be used later to build the system.
    -if they inherit from other systems, merge their values before saving them. The result of the above example would look like this:
    [/list:u]
    caelum_sky_system MySystem
    {
    julian_day 2451545.0

    point_starfield {
    mag0_pixel_size 16
    min_pixel_size 5
    max_pixel_size 7
    }
    }


    Step 2 - parse the script and build the system:
    This will happen when the user calls a method.

    -iterate through all properties of the script
    1. -return whether the property is a parent node
      -if the property isn't a parent, return it's the name and value (as a string)
      -if the property is a parent (like 'point_starfield'), return its name and iterate through its children[/list:u]

      The values will be injected with reflection.
      Errors will be logged with LogManager and the parsing will continue gracefully.
      Defaults are set in the constructor.

      If the author of Caelum would had used XML files instead, it would be easy to check for right syntax and values by XML Schemas (XSD files). Also it would be easy to import / export the settings with only a few lines of code (really few).
      Funny, that's exactly what I thought.

Beauty

13-03-2009 16:34:58

I think we should keep the config files compatible with original Caelum.

The inherits I didn't recognized, but this should be no big problem.
Is there a multiple inherit possible or only single ones?

Example:
base
{
...
}
inherit : base
{
...
}
inherit2 : inherit
{
...
}


Is there a whish to keep the original inherit groups if you save a setting?
Because if you merge it, use it and save it later, then the inherit groups are gone.

-----------------------------------------------

To use a Dictionary<> is a nice way for processing.
The problem is, that all values are still in String format.

What's about using a Hash that also includes the right datatype?
So we can load and check the entries
* load entry
* check syntax etc.
* convert to right datatype
* save entry in hash (including datatype information)

Definition:
Dictionary<String, ConfigEntry> config;

struct ConfigEntry
{
public String property;
public Type datatype;
public Object value;
public Boolean isDefault; // optional, for overwriting default values
public String parent; // optional, for saving name of parent (if inherit)
}


I wrote a test application:
* save a test entry to the dictionary (name: config)
* call ReadEntry(...) for loading data
* write result

The idea of ReadEntry(...) is:
* read entry from config and store to targetVar
* only this singe method is needed for all kinds of datatypes
* before returning value: check the DataType of targetVar and entry.datatype (has to be the same)
* the value should be saved to targetVar in the right DataType

My test application:
using System;
using System.Collections.Generic;
using System.Text;
using Mogre;


namespace CaelumConfig
{
class Program
{


static void Main(string[] args)
{
Test test = new Test();
}


} // Program




class Test
{
Dictionary<String, ConfigEntry> config; // hash

public Test()
{
config = new Dictionary<String, ConfigEntry>();

// example
Vector2 cloudSpeed = new Vector2(1, 2);

// save this example entry to hash
ConfigEntry entry = new ConfigEntry();
entry.name = "cloud_speed";
entry.datatype = cloudSpeed.GetType();
entry.value = cloudSpeed;
entry.isDefault = false;
entry.parent = ""; // root
config.Add(entry.name, entry); // store in hash


Vector2 loadedValue = new Vector2();
ReadEntry("cloud_speed", loadedValue);

Console.WriteLine("Result: " + loadedValue.ToString());
Console.WriteLine("\npress any key to exit");
Console.ReadKey();


}

public void ReadEntry(String valueName, Object targetVar)
{
// return if key not found
if (!config.ContainsKey(valueName))
{
Console.WriteLine("Key not found: " + valueName);
return;
}

// read value
ConfigEntry entry = config[valueName];
// check for correct type
if (targetVar.GetType() != entry.datatype)
{
Console.WriteLine(String.Format("Wrong type in {0}: '{1}' vs '{2}' ",
valueName, targetVar.GetType().ToString(), entry.datatype.ToString()));
return;
}

Type type = targetVar.GetType();
// targetVar = (type)(entry.value); // ERROR: var "type" var doesn't work
targetVar = (Vector2)(entry.value); // just for testing of method

} // ReadEntry


} // class Test




struct ConfigEntry
{
public String name;
public Type datatype;
public Object value;
public Boolean isDefault; // optional, for overwriting default values
public String parent; // optional, for saving name of parent (if inherit)
}

}



problem 1:
the param targetVar is only for input, not for output

* if I use ref there is an error
ReadEntry(String valueName, ref Object targetVar)

* if I add one more param with out then I get an other error:
....... Can't convert Vector2 to Object.
ReadEntry(String valueName, Object targetVar, out Object targetVarOut)

problem 2:
Type type = targetVar.GetType(); I can store the DataType to a var
targetVar = (type)(entry.value); But I can't use this for determining the type of targetVar


Does somebody has an idea how to solve the problems?
To use one single method for all datatypes would be nice.
If there is no solution I have to define a method for every possible DataType.

Beauty

13-03-2009 16:38:58

cloud_system {
cloud_layer {
height 500
}
}


Is there a special name for such config files?
Maybe there are still parsing classes available.
This could be possible if this is a common file format.

smiley80

13-03-2009 18:41:08

Is there a multiple inherit possible or only single ones?
No multiple inheritance at once, but an inheritance chain like the one in your example.

Is there a whish to keep the original inherit groups if you save a setting?
Currently, Caelum hasn't the ability to save systems back to file.

The problem is, that all values are still in String format.
Not a problem at all.
Converting to the correct type will be done when setting the property value.

E.g.:
I have a Dictionary<string, PropertyInfo> BaseSkyLightProperties.
This dictionary is filled with the properties and their script names.
BaseSkyLightProperties.Add("auto_disable_threshold", typeof(BaseSkyLight).GetProperty("AutoDisableThreshold"));
Setting the value would be something like that:

PropertyInfo pi = BaseSkyLightProperties["auto_disable_threshold"];
object value = Convert.ChangeType(propertyValue, pi.PropertyType);
pi.SetValue(myBaseSkyLight, value, null);

Primitive types are easy to convert, ColourValue and Vector3 would require a (tiny) bit more work.

Beauty

13-03-2009 19:28:27

Converting to the correct type will be done when setting the property value.
This is possible, but I think my way could be better.

* read entries from file
* check right syntax (or other rules)
* save value only if it is ok
* if check failed a concrete message will be logged

advantage:
All entries will be checked after reading the config file, before Caelum itself starts the work.
Errors within the execute of Caelum is not nice.

I don't want write a syntax check for each possible entry (like the original).
Instead use a few methods that can handle with many entries.
Example:
CheckCountOfParams(String entry, Int32 count)
...... CheckCountOfParams("auto_disable_threshold", 1) means "1 param needed, not less, not more", Error logging is also inside

Store all checked entries with the right DataType is nice, because you just have to use it later.
Don't need a check when you use it.


For my Type problem I got an idea:
Use overlayed methods (I hope the translated word is right).
You define if for several output types, but the method name is the same. I think this is possible with C#.

Sorry I have to go to my second work (a disco), can't write more (or better).
I'm still to late now.
See you ...

smiley80

14-03-2009 17:13:12


* read entries from file
* check right syntax (or other rules)
* save value only if it is ok
* if check failed a concrete message will be logged

That's the plan. But it won't be done with the script parser itself. The parser only returns the name and the value. The reflection method checks the syntax.

CheckCountOfParams(String entry, Int32 count)
...... CheckCountOfParams("auto_disable_threshold", 1) means "1 param needed, not less, not more", Error logging is also inside

IMHO it's easier when the parser, for instance, returns name = "minimum_ambient_light" and value = "0.1 0.1 0.3".
Value is split into an object array.
The reflection method knows that 'minimum_ambient_light' is a ColourValue and expects that the array has a length of 3 or 4.
For primitive types and strings it expects an array length of 1.

Beauty

14-03-2009 18:20:20

I didn't know that you want to allocate the work.
Last night I thought more about. Whith the right concept it wouln't be much work to integrate the checks and converts. Just a few methods. Then all params are valide, converted and ready to use (without conversion and checks).
Also it would be easy to add more params in future.

The keywords and target types are in a list.
An other list contains the count of params for each type.
Then a few methods for doing the job, independent of the count of keywords.

In the result you just call:
pi.SetValue(myBaseSkyLight, ReadEntry("auto_disable_threshold"), null);
instead of your example:
PropertyInfo pi = BaseSkyLightProperties["auto_disable_threshold"];
object value = Convert.ChangeType(propertyValue, pi.PropertyType);
pi.SetValue(myBaseSkyLight, value, null);



The source of Caelum parser code looks awful to me, because of so many redundant lines for every param.
This example is for only one param (24 lines!):
235 bool TypeDescriptorScriptTranslator::getPropValueOrAddError (
236 ScriptCompiler* compiler,
237 PropertyAbstractNode* prop,
238 Ogre::Vector3& value)
239 {
240 if (prop->values.size () == 0) {
241 compiler->addError (ScriptCompiler::CE_STRINGEXPECTED, prop->file, prop->line);
242 return false;
243 }
244 if (prop->values.size () > 3) {
245 compiler->addError (ScriptCompiler::CE_FEWERPARAMETERSEXPECTED, prop->file, prop->line,
246 prop->name + " must have at most 3 arguments");
247 return false;
248 }
249 float floats[3];
250 if (!Ogre::ScriptTranslator::getFloats(prop->values.begin(), prop->values.end(), floats, 3)) {
251 compiler->addError (ScriptCompiler::CE_INVALIDPARAMETERS, prop->file, prop->line,
252 "incorrect vector parameters.");
253 return false;
254 }
255 value.x = floats[0];
256 value.y = floats[1];
257 value.z = floats[2];
258 return true;
259 }




Is there a list of all params, their types etc?


Is this your wanted way?

1) Parser:
* read file, merge inherits
* save values as String

2) Reflection:
* check for count of params / right syntax
* write log message if error
* convert and save values

3)
* start Caelum (if no error in reflection)
* use saved values

Beauty

15-03-2009 02:44:45

The values will be injected with reflection.
I'm not shure what you mean.


What means abstract?
Will that only be used for inherits?


Which key for Dictionary<String, String> we use for params that are in subgroups?
Can you write please, what should be the resulting entries in the dictionary. (for this example)

caelum_sky_system MySystem {
julian_day 2451545.0
point_starfield {
mag0_pixel_size 16
min_pixel_size 5
max_pixel_size 7
}
}

smiley80

15-03-2009 10:48:08


2) Reflection:
* check for count of params / right syntax
* write log message if error
* convert and save values

3)
* start Caelum (if no error in reflection)
* use saved values

These are combined.

First, the CaelumSystem is created:
myCaelumSystem = new CaelumSystem(root, sceneMgr, CaelumSystem.CaelumComponent.None);

then the script is loaded:
CaelumSharp.LoadScript(myCaelumSystem, "NameOfScript");

After that, the events are added and Caelum starts working.

The values will be injected with reflection.
I'm not shure what you mean.

That's the PropertyInfo stuff.

What means abstract?
Will that only be used for inherits?

Yes.

Which key for Dictionary<String, String> we use for params that are in subgroups?
Can you write please, what should be the resulting entries in the dictionary. (for this example)

The key will be the script name 'MySystem', the value should look exactly like your example.

As for the value parsing:
I think, I'll use StringReader and line-by-line parsing for that.

The only question left is how to merge the scripts.

Beauty

16-03-2009 04:56:31

I'm confused. I thought all singe params should be saved in a dictionary instead of an unparsed group.


Now I made the first big step.
After some hours I got a working code.
All comments will be removed at loading (single line and multiline).
Then my test application parses the outher groups of TestSkyScript.os.

The inner groups can be parsed the same way. (use of CatchGroup(...) for content of a group to get its inner groups)
But now I have no more time to extend the code.
In some days I will continue.

It was more difficult than I thought.
Especially because Regex of .NET doesn't support recursions (what is bad for subgroups).
But I found an alternative way by dynamic creation of a search pattern.

Here is my code if you want to see it:
http://beauty.online.de/pub/CaelumConfig_2009-03-15.rar

smiley80

16-03-2009 14:46:59

Thanks a lot, Beauty.

I'll give it a try after I've fixed the remaining bugs. And that shouldn't take much time...

As a teaser:


Early dawn

Beauty

16-03-2009 16:25:32

Nice picture :)


The parser code I'll improve later for catching subgroups, subsubgroups, values.
Also I want to add a useful way to save the params (like diskussed above).


How does the reflection work?
How will the height value be called in original Caelum? (for this example)

caelum_sky_system DefaultSky: DefaultBase
{
cloud_system
{
cloud_layer
{
height 3000
coverage 0.3
}
}
}


I can create a method, with which you can get the param like this:
ReadEntry(group, param, type)
The group is like a path for directories.
The group seperator can be "...", what is a good visible way.

Example:
Double height = ReadEntry("caelum_sky_system...DefaultSky...cloud_system...cloud_layer", "height", "double")


Would this be a good usable solution for you?
You just need one line to get the wanted value.

smiley80

18-03-2009 14:05:04

Okay, I've now a working script reader and merger.

The plain text gets converted into this class:

class ScriptNode
{
public string Name { get; set; }
public ScriptNodeCollection Nodes { get; set; }
public Dictionary<string, string[]> Values { get; set; }
}


Which is stored in a KeyedCollection.

So, now I only have to implement the reflection.


How does the reflection work?
How will the height value be called in original Caelum? (for this example)

Caelum uses function pointers.

Beauty

18-03-2009 18:57:41

Okay, I've now a working script reader and merger.
Nice. Did you extend my code or found / created an other one?
Later I recodnized that I forgot the catch of values. My code only looks for groups. This should be my next task I thought.

class ScriptNode
Which is stored in a KeyedCollection.

Aware: If you have a global list that only use the ScriptNode name then you can get in trouble, because if several groups use the same name then the old entries of the collection will be overwrited.

Oh, now I saw that there is a tricky group which contains subgroups with the same name.
The name postfix is Test. What should be the sense? If we use a Dictionary, we would overwrite the entries. I suppose instead all of them should be included. So a List<> could be better then a Dictionary.

caelum_sky_system CloudFadeScriptTest: DefaultBase
{
cloud_system {
cloud_layer {
height 300
coverage 0.3
cloud_uv_factor 3000

near_fade_dist 500
far_fade_dist 600
}

cloud_layer {
height 500
coverage 0.3
cloud_uv_factor 3000

near_fade_dist 500
far_fade_dist 600
}

cloud_layer {
height 700
coverage 0.3
cloud_uv_factor 3000

near_fade_dist 500
far_fade_dist 600
}
}
}




How does the reflection work?
How will the height value be called in original Caelum? (for this example)

Caelum uses function pointers.

Does it means that the pointed functions are parser functions which search for the wanted value in the merged datafile? Or just read a variable and return it?
What is the difference to my suggestion of ReadEntry(group, param, type) or is it similar?

Beauty

18-03-2009 22:08:42

If you still need help and if I shall improve my test application, just tell me.
Now I have some time again.

smiley80

19-03-2009 08:50:13


Nice. Did you extend my code or found / created an other one?
Later I recodnized that I forgot the catch of values. My code only looks for groups. This should be my next task I thought.

I've changed CatchGroup a bit. Return type is now bool. Returns true if there might be other groups, false if it has finished. And it only removes the found group from the content, so I can get the values from the remaining text.

Aware: If you have a global list that only use the ScriptNode name then you can get in trouble, because if several groups use the same name then the old entries of the collection will be overwrited.

As for CloudLayers:
They get saved as subnodes of CloudSystem in a KeyedCollection. If they don't have a special name, a number is added to the name to avoid nodes with the same name.

Does it means that the pointed functions are parser functions which search for the wanted value in the merged datafile? Or just read a variable and return it?
What is the difference to my suggestion of ReadEntry(group, param, type) or is it similar?

A lot of it is done in OgreScriptTranslator(hence the original topic question). Function pointers are a bit like delegates.


However, reflection is now implemented and everything seems to work fine. But I need some additional time for testing before the release.

Beauty

19-03-2009 11:57:45

I've changed CatchGroup a bit. Return type is now bool. Returns true if there might be other groups, false if it has finished. And it only removes the found group from the content, so I can get the values from the remaining text.
I made some more tests.
The catched group title is right, independent if the curly bracket is in the same line ore before.
BUT: Items that are above a group will be removed!

I know how to fix this problem, but have no more time at the moment.
This night I'll fix the problem.

Here is a test file. Item 3 + 4 will be killed.
xTEST { content xTEST } // comment after code

xTEST2 { content xTEST2 } /*
multiline comment {}
*/


TEST ITEM 3

TEST Group after Item 3 {
curly bracket in line of group name
content of group 3
}

TEST ITEM 4

TEST Group after Item 4
{
curly bracket after line of group name
content of group 4

}



However, reflection is now implemented and everything seems to work fine. But I need some additional time for testing before the release.
Nice to hear that processing of ressource files generally works now.


Thanks for the explanations.
I looked to the help for Dictionary and KeyedCollection, but I don't understand the difference. Do you know it?

Beauty

20-03-2009 02:01:45

Sorry I didn't fix the problem today. Had to do something else. But tomorrow I can do.

smiley80

20-03-2009 11:36:57

I looked to the help for Dictionary and KeyedCollection, but I don't understand the difference. Do you know it?
The difference is, that the the key in a KeyedCollection is part of the value.

Beauty

21-03-2009 04:38:33

I got it. You just need to change one simple line.
(Don't forget the comma instead of a plus symbol)

// OLD
content = content.Substring(catched.Index + catched.Length);
//NEW
content = content.Remove(catched.Index , catched.Length);

The updated test application is here:
http://beauty.online.de/pub/CaelumConfig_2009-03-20.rar

CatchGroup(...) now returns a Boolean (like your idea).
Changed code I remarked with comment line "CODE UPDATE"

Beauty

21-03-2009 05:08:40

We should think about a name for your port.
Examples: Caelumm, CaelumM, MCaelum, Moelum, Mogre Caelum, Caelumo, Smiley Sky

Then we create an own wiki page for it.
It would be nice if you document the differences there.
Also write the related version of the original Caelum to the wiki and the source code.

smiley80

23-03-2009 08:38:29

Then we create an own wiki page for it.
Done

Beauty

23-03-2009 11:37:57

Thanks for creating the wiki page.
Now I also can look to your source code.

There I see you used an alternative way to fix the lost of items problem. Interesting.
// my suggestion
content = content.Remove(catched.Index , catched.Length);

// your solution
string rem = content.Substring(catched.Index, catched.Length);
content = content.Replace(rem, string.Empty);


By the way - your tribute to me is not visible on google page, because it's behind the changelog box :lol:
I linked the page from Caelum wiki page.

cdleonard

23-03-2009 12:24:17

Hello; I'm the current maintainer of Caelum.

This topic is very very strange.

Are you people trying to reimplement ogre script parsing using regular expressions? That doesn't seem like a good idea.

The reason caelum uses scripts instead of XML files is to benefit from the inheritance logic in ogre scripts and better integrate with Ogre; and also because I thought it would be useful to learn more about ogre scripting.

Caelum gets all the fancy 1.6 scripting features for free; including stuff like imports and variables. A full port of caelum scripts requires a full port of ogre's new script compilers; and those are absolutely huge and full of STL code.

Still; this is an interesting endeavour. If you have sourceforge.net accounts I can give you access to caelum's svn.

smiley80

23-03-2009 14:09:04


There I see you used an alternative way to fix the lost of items problem. Interesting.

Yeah. But since String.Replace may be buggy in some scenarios, I'll switch to String.Remove.

By the way - your tribute to me is not visible on google page, because it's behind the changelog box :lol:

Maybe on 1024x768, but not on 1440x900... :wink:


The reason caelum uses scripts instead of XML files is to benefit from the inheritance logic in ogre scripts and better integrate with Ogre; and also because I thought it would be useful to learn more about ogre scripting.

Caelum gets all the fancy 1.6 scripting features for free; including stuff like imports and variables. A full port of caelum scripts requires a full port of ogre's new script compilers; and those are absolutely huge and full of STL code.

Inheritance and overrides are implemented. Imports and variables are currently missing (I've updated my post to reflect that), but will be supported in the future.

But of course 100% script compability between Caelum and CaelumSharp will only be possible, if I have access to Ogre's script loader via Mogre.

If you have sourceforge.net accounts I can give you access to caelum's svn.
I've already setup a Google Code project:
http://code.google.com/p/caelumsharp/

Beauty

23-03-2009 14:56:54

Hello; I'm the current maintainer of Caelum.
Hi, this is a little surprice. Thanks for your interest and post :)

This topic is very very strange.
Interesting that it affects sooooo strange :lol:

Are you people trying to reimplement ogre script parsing using regular expressions?
I think you're right.

That doesn't seem like a good idea.
Now I got shocked ...

The reason caelum uses scripts instead of XML files is to benefit from the inheritance logic in ogre scripts and better integrate with Ogre; and also because I thought it would be useful to learn more about ogre scripting.
Thanks for sharing your thoughts.
By the way - Inheritances are also possible with XML.
I concede that the Ogre way of config file is nice for editing by simple text editors. For XML files it's not so clear and an XML editor would the better choice.

As I understood with Mogre it would be not possible to use the parsing methods of Caelum. Maybe the parser classes are not wrapped? So there was the need for an other way.
I wanted to see how the parse of Ogre script files is done, but I didn't found the related code.

In my Perl programming time I got experiences with Regular Expressions which are great for such tasks. So I could help out of this situation.
By the way - in Perl 6 these are extendet so that you can define complex patterns including inherits (I suppose). So it's easy to write parsers or validators for complex data structures (e.g. source code of a programming language). But we don't live in the Perl world now, ... although it's possible that other languages will adopt the idea.

Caelum gets all the fancy 1.6 scripting features for free; including stuff like imports and variables. A full port of caelum scripts requires a full port of ogre's new script compilers; and those are absolutely huge and full of STL code.
I didn't know about improvements of the Ogre script classes. Somewhere in the ogre API I read that these are only basic functions for config file access. Ok, there are several script related classes. Maybe I didn't found the advanced one.
We want to keep CaelumSharp compatible to the main project.
If you have examples for config files with other features than your current example script then tell me and I try to extend my regex parser. Although I suppose that not all script file improvements of the ogre classes are needed for Caelum.
In this post I wrote about my basic thoughts for an own parser, which you possibly didn't read (because of so much text), but maybe this is interesting for you. Smiley80 used an other way, but it works for the example file and this is the important thing.
Also I thought about to write a converter for Ogre config style --> XML. But this could be more work and I don't know if there is a need.

Still; this is an interesting endeavour.
It seems so that you changed your opinion (in comparison to your first lines) ;-)

Still; this is an interesting endeavour. If you have sourceforge.net accounts I can give you access to caelum's svn.
I still don't have an account there, but could create it if there is a need. Why you ask? To make changes in the script loader functionality?? I suppose you mean for general improvements or new ideas. For this I can't help, because I don't understand C++ very well. But if you have special questions for regular expressions you can ask me.