/// <summary> /// 評価用メソッド. /// </summary> /// <param name="context">コンテキストオブジェクト.</param> public override void Interpret(GeneratorContext context) { DebugLog("NonterminalExpression.Interpret(): " + Name); // 戻り値の準備 Result result = new Result(Name); //Matches = new TokenMatches(Name); //IsMatch = false; if (context.Fields.ContainsKey(Name) == false) { throw new InterpreterException("NonterminalExpression.Interpret() Error"); } GeneratedExpression exp = context.Fields[Name]; exp.Interpret(context); Result itemResult = context.PopResult(); result.IsMatch = itemResult.IsMatch; result.Matches.ConcatTokens(itemResult.Matches); context.PushResult(result); }
/// <summary> /// 評価用メソッド. /// </summary> /// <param name="context">コンテキストオブジェクト.</param> public override void Interpret(GeneratorContext context) { // 一番深い要素を探す GeneratedExpression exp = GetDeepestExpression(context, this); if (exp == null) { ThrowParseException( ErrorMessages.ExpressionNotFound ); } // 見つかった要素を実行する DebugLog("RootExpression: (" + exp.Name + ")"); exp.Interpret(context); Result itemResult = context.PopResult(); // 最後のトークンをチェックする Token <TokenType> token = context.Current; if (itemResult.IsMatch == false || token != null) { ThrowParseException( ErrorMessages.UnexpectedToken, token ); } }
/// <summary> /// 一番深い Expression を探す. /// </summary> /// <param name="context">コンテキスト.</param> /// <param name="root">ルート要素.</param> /// <returns>一番深い要素.</returns> private GeneratedExpression GetDeepestExpression(GeneratorContext context, RootExpression root) { int maxDepth = 0; GeneratedExpression target = null; foreach (GeneratedExpression exp in root.Expressions) { int depth = GetDepth(context, exp); if (depth > maxDepth) { maxDepth = depth; target = exp; } DebugLog("RootExpression.Expressions : (" + exp.Name + ", " + depth + ")"); } return(target); }
/// <summary> /// 指定された Expression の深さを取得する. /// </summary> /// <param name="context">コンテキスト.</param> /// <param name="expression">Expression.</param> /// <param name="names">無限ループ抑止用.</param> /// <returns>深さ.</returns> private int GetDepth(GeneratorContext context, GeneratedExpression expression, List <string> names = null) { if (names == null) { names = new List <string>(); } int max = 0; foreach (GeneratedExpression exp in expression.Expressions) { if (exp.Type == ExpressionType.Terminal) { continue; } int depth = 0; if (exp.Type == ExpressionType.Nonterminal) { if (names.Contains(exp.Name) == false) { names.Add(exp.Name); GeneratedExpression field = context.Fields[exp.Name]; depth = GetDepth(context, field, names) + 1; } } else { depth = GetDepth(context, exp, names) + 1; } if (depth > max) { max = depth; } } return(max); }
/// <summary> /// Expression を追加する. /// </summary> /// <param name="exp"></param> public void AddExpression(GeneratedExpression exp) { Expressions.Add(exp); }
/// <summary> /// 評価用メソッド. /// </summary> /// <param name="context">コンテキストオブジェクト.</param> public override void Interpret(GeneratorContext context) { DebugLog("LoopExpression.Interpret(): " + Name + ", " + Expressions.Count); // 戻り値の準備 Result result = new Result(Name); int maxCount = 0; foreach (GeneratedExpression exp in Expressions) { if (exp.Type != ExpressionType.Option) { maxCount++; } } bool loop = true; while (loop) { int count = 0; GeneratedExpression exp2 = null; foreach (GeneratedExpression exp in Expressions) { exp2 = exp; DebugLog("LoopExpression.Expressions : (" + exp.Name + ")"); exp.Interpret(context); Result itemResult = context.PopResult(); result.IsMatch = itemResult.IsMatch; if (itemResult.IsMatch == false) { if (exp.Type == ExpressionType.Option) { continue; } DebugLog("-\texp.IsMatch == false : (" + exp.Name + ")"); break; } result.Matches.ConcatTokens(itemResult.Matches); //Matches.ConcatTokens(exp.Matches); count++; } if (count == 0) { //Console.WriteLine("LoopExpression: count == 0: " + exp2.Type + ", " + exp2.Name); break; } if (count == maxCount) { } if (count != maxCount) { ThrowParseException( ErrorMessages.UnexpectedToken, context.Current ); } Token <TokenType> token = context.Current; if (token == null) { loop = false; break; } } context.PushResult(result); //Matches = matches; }