public void AddRule(BnfRule rule) { NonTerminalToken lhs = rule.LeftHandSide; foreach (BnfRule ruleIn in rules) { if (lhs.equals(ruleIn.LeftHandSide)) { ruleIn.AddPossibilities(rule.GetPossibilities()); break; } } this.rules.Add(rule); // No rule with the same LHS found }
public ParseNode Parse(BnfRule rule, ref string input, int recursionStep, int lineNum) { // When the maximum recursion depth is reached program throws exception. if (recursionStep > maxRecursionSteps) { throw new Exception(string.Format("Max. number of recursion steps reached. Error line : {0}", lineNum)); } ParseNode node = null; bool wrongToken = true; string inputCpy = ""; inputCpy += input; foreach (TokenList poss in rule.GetPossibilities()) { node = new ParseNode(); node.Token = node.Value = rule.LeftHandSide.Name; TokenList newPossib = poss.getCopy(); IEnumerator <Token> possibIterator = newPossib.GetEnumerator(); wrongToken = false; inputCpy = ""; inputCpy += input; while (possibIterator.MoveNext() && !wrongToken) // checks if it has next token { inputCpy = inputCpy.Trim(); Token possToken = possibIterator.Current; if (possToken is TerminalToken) { if (string.IsNullOrEmpty(inputCpy)) { wrongToken = true; break; } int limit = possToken.match(inputCpy); if (limit > 0) { ParseNode child = new ParseNode(); string inputSubstring = inputCpy.Substring(0, limit); inputCpy = inputCpy.Remove(0, inputSubstring.Length); if (possToken is RegexTerminalToken) { child = AddRegexToken(child, (RegexTerminalToken)possToken, inputSubstring); } child.Token = inputSubstring; node.AddChild(child); } //else if (limit == -1) //{ // if (possToken is StandardExpressionTerminalToken && !((StandardExpressionTerminalToken)possToken).IsItAMatch(inputCpy)) // throw new Exception("Regex not mached [" + possToken.Name + "] -> " + inputCpy + "\n"); // else if (possToken is BigCityTerminalToken && !((BigCityTerminalToken)possToken).IsItAMatch(inputCpy)) // throw new Exception("City not mached! City: " + inputCpy + "\n"); //} else // No match; rule expects token { wrongToken = true; node = null; break; } } else // Parse non-terminal token { ParseNode child = null; BnfRule newRule = GetRule(possToken); if (newRule == null) { throw new Exception("There is rule missing for the non-terminal token '" + possToken.Name + "'!\n"); } child = Parse(newRule, ref inputCpy, recursionStep + 1, lineNum); if (child == null) // Parsing failed! { wrongToken = true; node = null; break; } node.AddChild(child); } } if (!wrongToken) { if (!possibIterator.MoveNext()) { if (recursionStep > 0 || (recursionStep == 0 && inputCpy.Trim().Length == 0)) { break; } } else { wrongToken = true; inputCpy = ""; inputCpy += input; break; } } } int consumedLength = input.Length - inputCpy.Length; if (wrongToken || consumedLength == 0) { return(null); } input = input.Substring(consumedLength); if (recursionStep == 0 && !string.IsNullOrEmpty(input)) { return(null); } return(node); }