I have a data interpretation algorithm & actual data. Using this algorithm, I have to interpret the actual data and display it as a report.
For this, Firstly I need to create a form which will accept some variable values from user. The variables are defined in pseudocode as below. (one example given)
AGEYEARS {
Description: Age in Years
Type: Range;
MinVal: 0;
MaxVal: 124;
Default: 0;
ErrorAction: ERT1:=04 GRT4:=960Z;
}
I have several variables like this in my Variables.txt file. I don't wish to use StreamReader, read it line by ine & interpret the variables.
Instead, I am looking for some logic, which can read XXXX { } as one object and Type:Range as Attribute:Value. This way, I can skip one step of reading the file and converting it to a understandable code.
Like this, I also have other files which has conditions to check. For ex, IF SEX = '9' THEN SEX:=U ENDIF
Is there any way to interpret them easily and faster? Can someone help me with it?
I am using C# as my programming language.
So you need a parser for a DSL.
I can advise you ANTLR, which will let you build a grammar easily.
Here's a totally untested simple grammar for it:
grammar ConfigFile;
file: object+;
object: ID '{' property+ '}';
property: ID ':' value ';';
value: (ID|CHAR)+;
ID: [a-zA-Z][a-zA-Z0-9_]*;
WS: [ \t\r\n]+ -> channel(HIDDEN);
CHAR: .;
Alternate solution: You also could use regex:
(?<id>\w+)\s*\{\s*(?:(?<prop>\w+)\s*:\s*(?<value>.+?)\s*;\s*)*\}
Then extract the captured information. For each match, you'll have a group id
with the name of the object. The groups prop
and value
will have multiple captures, each pair defining a property.
In C#:
var text = @"
AGEYEARS {
Description: Age in Years;
Type: Range;
MinVal: 0;
MaxVal: 124;
Default: 0;
ErrorAction: ERT1:=04 GRT4:=960Z;
}
OTHER {
Foo: Bar;
Bar: Baz;
}";
var re = new Regex(@"(?<id>\w+)\s*\{\s*(?:(?<prop>\w+)\s*:\s*(?<value>.+?)\s*;\s*)*\}");
foreach (Match match in re.Matches(text))
{
Console.WriteLine("Object {0}:", match.Groups["id"].Value);
var properties = match.Groups["prop"].Captures.Cast<Capture>();
var values = match.Groups["value"].Captures.Cast<Capture>();
foreach (var property in properties.Zip(values, (prop, value) => new {name = prop.Value, value = value.Value}))
{
Console.WriteLine(" {0} = {1}", property.name, property.value);
}
Console.WriteLine();
}
This solution is not as "pretty" as the parser one, but works without any external lib.