/// <summary> /// 解析一个Block /// </summary> /// <param name="Lex">词法分析器</param> /// <returns>解析结果</returns> private static ASTNode_StatementList ParseBlock(Lexer Lex) { ASTNode_StatementList tRet; if (TryMatchToken(Lex, Lexer.Token.LeftBrace)) // { { tRet = ParseStatementList(Lex); MatchToken(Lex, Lexer.Token.RightBrace); // } return(tRet); } else // 单条语句 { ASTNode_Statement tStatement; if (ParseStatement(Lex, out tStatement)) { tRet = new ASTNode_StatementList(); tRet.Statements.Add(tStatement); return(tRet); } else { throw new SyntaxException(Lex.Position, Lex.Line, Lex.Row, String.Format("unexpected token {0}.", Lex.FormatCurrentToken())); } } }
/// <summary> /// 解析一个块中的StatementList /// </summary> /// <param name="Lex">词法分析器</param> /// <returns>解析结果</returns> private static ASTNode_StatementList ParseStatementList(Lexer Lex) { ASTNode_StatementList tRet = new ASTNode_StatementList(); ASTNode_Statement tStatement; while (ParseStatement(Lex, out tStatement)) { tRet.Statements.Add(tStatement); } return(tRet); }
/// <summary> /// 执行一个区块 /// </summary> /// <param name="StatementList">语句列表语法树</param> public void ExecBlock(ASTNode_StatementList StatementList) { foreach (ASTNode_Statement s in StatementList.Statements) { switch (s.Type) { case ASTNode.ASTType.Assignment: { ASTNode_Assignment tAssignment = (ASTNode_Assignment)s; object tResult = ExecExpression(tAssignment.Expression); if (!_Environment.ContainsKey(tAssignment.IdentifierLower)) { _Environment.Add(tAssignment.IdentifierLower, tResult); } else { _Environment[tAssignment.IdentifierLower] = tResult; } } break; case ASTNode.ASTType.Call: { ASTNode_Call tCall = (ASTNode_Call)s; applyCallOperator(tCall.Identifier, tCall.IdentifierLower, tCall.ArgList, s.LineNumber); } break; case ASTNode.ASTType.ForStatement: { ASTNode_ForStatement tForStatement = (ASTNode_ForStatement)s; object tFromResult = ExecExpression(tForStatement.FromExpression); object tToResult = ExecExpression(tForStatement.ToExpression); object tStepResult = tForStatement.StepExpression == null ? null : ExecExpression(tForStatement.StepExpression); doForLoop( tForStatement.Identifier, tForStatement.IdentifierLower, tFromResult, tToResult, tStepResult, tForStatement.ExecBlock, s.LineNumber ); } break; default: throw new RuntimeException(s.LineNumber, "internal error."); } } }
/// <summary> /// 解析语法树 /// </summary> /// <param name="Lex">词法分析器</param> /// <returns>语法树</returns> public static ASTNode_StatementList Parse(Lexer Lex) { Lex.Next(); // 预读取第一个词法单元 ASTNode_StatementList tRet = ParseStatementList(Lex); if (Lex.CurrentToken != Lexer.Token.EOF) { throw new SyntaxException(Lex.Position, Lex.Line, Lex.Row, String.Format("unexpected token {0}.", Lex.FormatCurrentToken())); } return(tRet); }
/// <summary> /// 提交源代码 /// </summary> /// <param name="SourceCode">源代码</param> public void SubmitSourceCode(string SourceCode) { if (_WorkThread != null && _WorkThread.IsAlive) { MessageBox.Show(this, "请先结束当前任务然后继续。", "正忙", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } if (SourceCode != _SourceCode) { _SourceCode = SourceCode; _AST = null; } _WorkThread = new Thread(new ThreadStart(workThreadJob)); _WorkThread.IsBackground = true; _WorkThread.Start(); }
// 执行for循环 private void doForLoop(string Identifier, string IdentifierLower, object From, object To, object Step, ASTNode_StatementList Block, int LineNumber) { if (!(From is double)) { throw new RuntimeException(LineNumber, "from expression must return a digit."); } if (!(To is double)) { throw new RuntimeException(LineNumber, "to expression must return a digit."); } double tFrom = (double)From; double tTo = (double)To; // 设置默认步长 if (Step == null) { if (tFrom <= tTo) { Step = 1.0; } else if (tFrom >= tTo) { Step = -1.0; } } if (!(Step is double)) { throw new RuntimeException(LineNumber, "step expression must return a digit."); } double tStep = (double)Step; // 赋予初值 if (!_Environment.ContainsKey(IdentifierLower)) { _Environment.Add(IdentifierLower, tFrom); } else { _Environment[IdentifierLower] = tFrom; } // 执行for循环 while (true) { // ! 当前的值可能在循环体中被用户代码改变。 object tCurrentObject = fetchValueOfIdentifier(Identifier, IdentifierLower, LineNumber); if (!(tCurrentObject is double)) { throw new RuntimeException(LineNumber, "for iterator must be a digit."); } double tCurrent = (double)tCurrentObject; // 检查循环是否结束 if (tFrom <= tTo && tCurrent > tTo) { break; } else if (tFrom > tTo && tCurrent < tTo) { break; } // 执行函数体 ExecBlock(Block); // Step计数 // ! 重新获取值 tCurrentObject = fetchValueOfIdentifier(Identifier, IdentifierLower, LineNumber); if (!(tCurrentObject is double)) { throw new RuntimeException(LineNumber, "for iterator must be a digit."); } tCurrent = (double)tCurrentObject + tStep; // 设置值 if (!_Environment.ContainsKey(IdentifierLower)) { _Environment.Add(IdentifierLower, tCurrent); } else { _Environment[IdentifierLower] = tCurrent; } } }
// 工作线程 private void workThreadJob() { Stopwatch tWatch = new Stopwatch(); // 初始化状态 this.Invoke((Action)initState); // 检查AST树是否已生成 if (_AST != null) { writeLog("忽略解析过程"); } else { writeLog("正在执行解析过程..."); // 解析代码 bool bCompileSucceed = false; using (StringReader tReader = new StringReader(_SourceCode)) { tWatch.Start(); try { lang.Lexer tLexer = new lang.Lexer(tReader); // 初始化Lexer _AST = lang.Syntax.Parse(tLexer); // 解析 bCompileSucceed = true; } catch (lang.LexcialException e) { writeLog("词法错误"); } catch (lang.SyntaxException e) { writeLog("语法错误"); } catch (Exception e) { writeLog("一般性错误"); } tWatch.Stop(); if (bCompileSucceed) { writeLog("解析成功,耗时:{0} 秒"); } else { writeLog("解析失败,耗时:{0} 秒"); } } } if (_AST != null) { // 执行语法树 PaintRuntime tRT = new PaintRuntime(); tRT.OnOutputText += delegate(PaintRuntime sender, string Content) { //writeOutputText(Content + "\r\n"); }; tRT.OnRuntimeException += delegate(PaintRuntime sender, lang.RuntimeException e) { writeLog("运行时错误"); }; // 执行 writeLog("正在执行..."); tWatch.Start(); tRT.RunAST(_AST); tWatch.Stop(); writeLog("执行完毕,耗时秒"); // 设置图片 this.Invoke((Action) delegate() { pictureBox_result.BackgroundImage = Resource.Icon_Busy;//tRT.TargetBuffer; pictureBox_result.Width = pictureBox_result.BackgroundImage.Width; pictureBox_result.Height = pictureBox_result.BackgroundImage.Height; }); } }