protected static void ParseMPGE(Grammar.Grammar grammar, string line) { string backup = line; LiteralGrammarElement SymbolKeyword = new LiteralGrammarElement("MultiGrammarElement "); if (SymbolKeyword.Validate(ref line, true).Result) { line = line.Trim(); string templine = line; SymbolSet AlphabetWithSpace = SymbolSet.FromType(SymbolSetPredefinedType.AlphaNumeric); AlphabetWithSpace.Add(new Symbol('_')); AlphabetWithSpace.Add(new Symbol('$')); AlphabetWithSpace.Add(new Symbol('/')); VariableLengthGrammarElement SymbolName = new VariableLengthGrammarElement(VariableLengthGrammarElementType.Plus, AlphabetWithSpace); if (SymbolName.Validate(ref line, true).Result) { string name = templine.Substring(0, templine.IndexOf(line)).Trim(); line = line.Trim(); LiteralGrammarElement EqualsSign = new LiteralGrammarElement("="); if (EqualsSign.Validate(ref line, true).Result) { line = line.Trim(); MultiParsePrecedenceType precedence = MultiParsePrecedenceType.Normal; if (line.LastIndexOf(',') >= 0) { string precedenceString = line.Substring(line.IndexOf(',') + 1).Trim(); line = line.Substring(0, line.IndexOf(',')).Trim(); LiteralGrammarElement precKey = new LiteralGrammarElement("precedence"); LiteralGrammarElement colon = new LiteralGrammarElement(":"); if (precKey.Validate(ref precedenceString, true).Result) { precedenceString = precedenceString.Trim(); if (colon.Validate(ref precedenceString, true).Result) { string[] precedenceList = Enum.GetNames(typeof(MultiParsePrecedenceType)); LiteralGrammarElement type = new LiteralGrammarElement(precedenceList); precedenceString = precedenceString.Trim(); if (type.Validate(ref precedenceString, false).Result) { precedence = (MultiParsePrecedenceType)Enum.Parse(typeof(MultiParsePrecedenceType), precedenceString); } else { throw new InfinityGrammarScriptParseError("Error", backup); } } else { throw new InfinityGrammarScriptParseError("Precedence is always followed by a Colon \":\"", backup); } } else { throw new InfinityGrammarScriptParseError("Invalid syntax. Only 'precedence' keyword allowed here", backup); } } string[] terminals = line.Split(new string[] { " or ", " | " }, StringSplitOptions.RemoveEmptyEntries); MultiParseGrammarElement mpge = new MultiParseGrammarElement(); mpge.Precedence = precedence; int count = 0; foreach (string ss in terminals) { try { GrammarElement cge = ParseCGE(grammar, ss); if (cge.Name == null || cge.Name == "") { cge.Name = name + ":" + count++; } mpge.AddTerminal(cge); } catch (KeyNotFoundException) { _temp.Add(backup); throw new InfinityGrammarScriptParseError("No such terminal to add to.", backup); } } grammar.AddTerminal(name, mpge); } else { throw new InfinityGrammarScriptParseError("MultiGrammarElement requires assignment after the name, missing '=' sign", backup); } } else { throw new InfinityGrammarScriptParseError("Check name", backup); } } else { throw new InfinityGrammarScriptParseError("Undetected error", backup); } }
protected static void ParseGrammarElement(ref Grammar.Grammar grammar, string line) { string backup = line; LiteralGrammarElement SymbolKeyword = new LiteralGrammarElement("GrammarElement "); if (SymbolKeyword.Validate(ref line, true).Result) { line = line.Trim(); string templine = line; SymbolSet AlphabetWithSpace = SymbolSet.FromType(SymbolSetPredefinedType.AlphaNumeric); AlphabetWithSpace.Add(new Symbol('_')); AlphabetWithSpace.Add(new Symbol('$')); AlphabetWithSpace.Add(new Symbol('/')); VariableLengthGrammarElement SymbolName = new VariableLengthGrammarElement(VariableLengthGrammarElementType.Plus, AlphabetWithSpace); if (SymbolName.Validate(ref line, true).Result) { string name = templine.Substring(0, templine.IndexOf(line)).Trim(); line = line.Trim(); LiteralGrammarElement EqualsSign = new LiteralGrammarElement("="); if (EqualsSign.Validate(ref line, true).Result) { line = line.Trim(); if (line.Contains(" or ") || line.Contains(" | ") || (line.Contains("precedence") && (line.Contains("Ascending") || line.Contains("Descending")))) { MultiParsePrecedenceType precedence = MultiParsePrecedenceType.Normal; if (line.IndexOf(',') >= 0) { string precedenceString = line.Substring(line.IndexOf(',') + 1).Trim(); line = line.Substring(0, line.IndexOf(',')).Trim(); LiteralGrammarElement precKey = new LiteralGrammarElement("precedence"); LiteralGrammarElement colon = new LiteralGrammarElement(":"); if (precKey.Validate(ref precedenceString, true).Result) { precedenceString = precedenceString.Trim(); if (colon.Validate(ref precedenceString, true).Result) { string[] precedenceList = Enum.GetNames(typeof(MultiParsePrecedenceType)); LiteralGrammarElement type = new LiteralGrammarElement(precedenceList); precedenceString = precedenceString.Trim(); if (type.Validate(ref precedenceString, false).Result) { precedence = (MultiParsePrecedenceType)Enum.Parse(typeof(MultiParsePrecedenceType), precedenceString); } } } } string[] terminals = line.Split(new string[] { " or ", " | " }, StringSplitOptions.RemoveEmptyEntries); MultiParseGrammarElement mpge = new MultiParseGrammarElement(); mpge.Precedence = precedence; int count = 0; foreach (string ss in terminals) { try { GrammarElement cge = ParseCGE(grammar, ss); if (cge.Name == null || cge.Name == "") { cge.Name = name + ":" + count++; } mpge.AddTerminal(cge); } catch (KeyNotFoundException k) { _temp.Add(backup); throw new InfinityGrammarScriptParseError("No such terminal to add to. " + k.Message, backup); } } grammar.AddTerminal(name, mpge); } else { string delimiters = " \n\r\t"; int idx = line.LastIndexOf(','); if (line.Substring(idx + 1).Trim().StartsWith("delimiters")) { delimiters = line.Substring(idx + 1).Trim(); line = line.Substring(0, idx); LiteralGrammarElement lge = new LiteralGrammarElement("delimiters"); if (lge.Validate(ref delimiters, true).Result) { delimiters = delimiters.Trim(); if (delimiters.StartsWith("[") && delimiters.EndsWith("]")) { delimiters = delimiters.Substring(1, delimiters.Length - 2); if (delimiters.Length == 0) { delimiters = "@None"; } } } else { throw new InfinityGrammarScriptParseError("Delimiters not declared properly - " + delimiters, backup); } } try { GrammarElement cge = ParseCGE(grammar, line, delimiters); grammar.AddTerminal(name, cge); } catch (KeyNotFoundException) { _temp.Add(backup); throw new InfinityGrammarScriptParseError("No such terminal to add to.", backup); } } } } } }