WEB开发网
开发学院软件开发C语言 仿查询分析器的C#计算器——5.计算求值 阅读

仿查询分析器的C#计算器——5.计算求值

 2009-03-31 08:21:50 来源:WEB开发网   
核心提示: 从代码中可以看出,首先是词法分析,仿查询分析器的C#计算器——5.计算求值(2),得到一个记号对象列表List<TokenRecord>,然后进行语法分析,"; } else { string strSource; int intTotalIndex = 0; thi

从代码中可以看出,首先是词法分析,得到一个记号对象列表List<TokenRecord>,然后进行语法分析,调用SyntaxTreeAnalyse的SnytaxTreeGetTopTokenAnalyse方法,分析出顶级记号对象,这样一棵树就出来了。接下来执行顶级节点的Execute方法,该方法中首先会执行下级节点的Execute方法,然后再针对下级节点的值执行自身的运算。所有的TokenRecord都是这样的模式,逐级递归调用,最后得到计算结果。TokenRecord基类中包含一个object类型的Value属性和一个Type类型的TokenValueType属性,通过这两个属性可以得到具体的值及其类型,然后做下一步处理。因为这里不只能执行数学运算,还能做字符串和逻辑值运算,所以必须通过TokenValueType来确定值的类型。如果只需要实现数学运算,程序会简单一些。

窗体的调用也很简单,并没有设计漂亮的外观和高级设置等。主要的代码是“计算”按钮的Click事件处理方法,代码如下:

        /// <summary>
        /// 点击“计算”按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnExecute_Click(object sender, EventArgs e)
        {
            if (this.rtbInput.Text.Trim().Replace("\n", "").Length == 0)
            {
                this.rtbOutput.Text = "输入的表达式不能为空,请重新输入。";
            }
            else
            {
                string strSource;
                int intTotalIndex = 0;
                this.rtbOutput.Text = "";
                string[] strLines;
                this.trvSyntaxTree.Nodes.Clear();//清空语法树

                if (this.rtbInput.SelectedText.Trim().Length == 0)//获取选中的代码,如果未选中,则执行全部
                {
                    strSource = this.rtbInput.Text;
                }
                else
                {
                    strSource = this.rtbInput.SelectedText;
                    intTotalIndex = this.rtbInput.SelectionStart;
                }

                if (this.chkAllowMultiLine.Checked)//判断是按多行执行还是单行执行
                {
                    strLines = strSource.Split(new char[] { '\n' });//多行则用换行符分割成多行
                }
                else
                {
                    strLines = new string[] { strSource.Replace("\n", "") };//单行则移除换行符成一行
                }

                foreach (string Line in strLines)
                {
                    if (Line.Trim().Length != 0)//避免中间出现空行
                    {
                        try
                        {
                            TokenRecord TokenTop = myAnalyse.Analyse(Line);//计算表达式
                            this.rtbOutput.Text += TokenTop.GetValueString() + "\n";//显示计算结果
                            this.LoadSyntaxTree(TokenTop);//加载语法树到TreeView控件
                        }
                        catch (Exception ex)
                        {
                            this.rtbOutput.Text += "发生错误\n" + ex.Message + "\n";//显示错误信息
                            if (ex is SyntaxException)//如果是语法错误,则选中错误的代码
                            {
                                SyntaxException myException = (SyntaxException)ex;
                                this.ActiveControl = this.rtbInput;//设置输入框为激活控件
                                this.rtbInput.Select(myException.Index + intTotalIndex, myException.Length);//定位发生错误的字符串
                            }
                            return;
                        }//try
                    }//if
                    intTotalIndex += Line.Length + 1;
                }//foreach
            }//else
        }//btnExecute_Click

上一页  1 2 3 4  下一页

Tags:查询 分析器 计算器

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接