⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ganalysis.cs

📁 关于CMM语言的解释器
💻 CS
📖 第 1 页 / 共 3 页
字号:
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.Collections;
using System.Windows.Forms;

namespace CmmInterpretor
{
    class GrammerAnalysis
    {
        //语法分析,获得分析结果
        public void AnalyzeCode(string sourceCode, ref string analysisText,
            ref TreeView gmTree)
        {
            bool isRemark = false;
            wordAnalysis.RemoveRemark(ref sourceCode, ref isRemark);
            sourceCode = Regex.Replace(sourceCode, @"[\t\n\r]", " ").ToString();

            //初步判断词法错误
            wordAnalysis.ErrorNum = 0; //归0(set方法已重载)
            string[] words = wordAnalysis.GetWords(sourceCode);
            foreach (string word in words)
                wordAnalysis.GetWordType(word); //该方法可计算错误单词数
            int errWordNum = wordAnalysis.ErrorNum;
            if (errWordNum > 0)
            {
                DialogResult response =
                    MessageBox.Show("代码中有" + Convert.ToString(errWordNum)
                                    + "个词法错误。是否要继续分析",
                    "确定", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                resultText += "代码中有"
                            + Convert.ToString(errWordNum) + "个词法错误。"
                            + "点击“词法分析”了解具体内容。\r\n\r\n";
                if (response == System.Windows.Forms.DialogResult.No)
                    return;
            }

            //获得语法树
            TreeForm treeForm = new TreeForm();
            treeForm.Show();
            trv = treeForm.getTree();
            trv.Nodes.Clear();
            trv.Nodes.Add("Source Code");

            //进行语法分析
            while (true)
            {
                CMMStatement curSt = SeparateFirstStatement(ref sourceCode);
                if (curSt.Type == NULLST)
                    break;
                else
                {
                    TreeNode stNode = GetNode(curSt);
                    if (stNode != null)
                        trv.Nodes[0].Nodes.Add(stNode);
                }
            }

            //更新语法树
            trv.Update();
            trv.ExpandAll();
            analysisText = resultText;
            gmTree = trv;
        }


        //由句首初步判断首语句类型
        private int InitType(string sourceCode)
        {
            sourceCode = sourceCode.TrimStart();

            //无语句
            if (sourceCode.Length == 0)
                return NULLST;

            //空语句
            if (sourceCode.StartsWith(";"))
            {
                return EMPTY;
            }

            //复合语句
            if (sourceCode.StartsWith("{"))
            {
                return COMPLEX;
            }

            foreach (string rsvw in ReservedWords)
            {
                //若语句首是关键字,则可直接进行初步判断
                if (sourceCode.StartsWith(rsvw) && sourceCode.Length > rsvw.Length)
                {
                    string[] wordtmp = wordAnalysis.GetWords(
                        sourceCode.Substring(0, rsvw.Length + 1));//多取一位排除干扰
                    switch (wordtmp[0])
                    {

                        case "int": //声明语句类型
                        case "real":
                            return DECLARE;


                        case "read"://输入语句类型
                            return INPUT;


                        case "write"://输出语句类型
                            return OUTPUT;


                        case "while"://循环语句类型
                            return LOOP;


                        case "if"://选择语句类型
                            return SELECT;


                        case "else"://if语句的else分支
                            return ELSE_BR;

                        //可能是与关键字相同开头的标识符
                        default:
                            break;
                    }
                }
            }
            //若句首没有关键字,则认为是赋值语句(如果是错误语句可在后续分析中判断出来)
            return ASSIGN;

            //是否为错误语句需要进一步判断
        }


        //分离sourceCode中的第一条语句
        public CMMStatement SeparateFirstStatement(ref string sourceCode)
        {
            CMMStatement curSt = new CMMStatement();
            sourceCode = sourceCode.TrimStart();
            curSt.Type = InitType(sourceCode);
            int firstSemi = sourceCode.IndexOf(";"); //第一个';'的位置

            switch (curSt.Type)
            {
                case NULLST: //无语句,无法分离
                    curSt.Con = "";
                    break;

                case EMPTY:  //空语句
                    curSt.Con = ";";
                    sourceCode = sourceCode.Remove(0, 1);
                    break;

                case COMPLEX:
                    string complexSt = "{";
                    if (GetBracketContent(ref sourceCode, ref complexSt))
                    {
                        complexSt += "}";
                    }
                    else
                    {
                        //若括号不匹配,则将代码全部剥离出来
                        complexSt += sourceCode;
                        sourceCode = "";
                    }
                    curSt.Con = complexSt;
                    break;

                case DECLARE: //声明语句
                case ASSIGN:  //赋值语句
                case INPUT:   //输入语句
                case OUTPUT:  //输出语句
                    if (firstSemi < 0)
                    {
                        //将代码全部剥离出来
                        curSt.Con = sourceCode;
                        sourceCode = "";
                        curSt.Type = ERROR;
                        dealError(curSt.Con, " 缺少';'");
                    }
                    else
                    {
                        //语句至第一个';'
                        curSt.Con = sourceCode.Substring(0, firstSemi + 1);
                        sourceCode = sourceCode.Remove(0, firstSemi + 1);
                    }
                    break;

                case LOOP:
                case ELSE_BR:
                    if (firstSemi < 0)
                    {
                        //将代码全部剥离出来
                        curSt.Con = sourceCode;
                        sourceCode = "";
                        curSt.Type = ERROR;
                        dealError(curSt.Con, " 缺少';'");
                        break;
                    }

                    curSt.Con = sourceCode.Substring(0, firstSemi + 1);

                    //第一个';'前的语句如果不包括'{',则不必进一步判断
                    if (!curSt.Con.Contains("{"))
                    {
                        sourceCode = sourceCode.Remove(0, firstSemi + 1);
                    }

                    //否则读取以"{"开头的复合语句
                    else
                    {
                        curSt.Con = sourceCode.Substring(0, sourceCode.IndexOf("{"));
                        sourceCode = sourceCode.Remove(0, sourceCode.IndexOf("{"));
                        CMMStatement cmpSt = SeparateFirstStatement(ref sourceCode);
                        curSt.Con += cmpSt.Con;
                    }
                    break;

                case SELECT:
                    if (firstSemi < 0)
                    {
                        //将代码全部剥离出来
                        curSt.Con = sourceCode;
                        
                        sourceCode = "";
                        dealError(curSt.Con, " 缺少';'");
                        break;
                    }

                    curSt.Con = sourceCode.Substring(0, firstSemi + 1);
                    //第一个';'前的语句如果不包括'{',则不必进一步判断
                    if (!curSt.Con.Contains("{"))
                    {
                        sourceCode = sourceCode.Remove(0, firstSemi + 1);
                    }
                    //否则读取以"{"开头的复合语句
                    else
                    {
                        curSt.Con = sourceCode.Substring(0, sourceCode.IndexOf("{"));
                        sourceCode = sourceCode.Remove(0, sourceCode.IndexOf("{"));
                        CMMStatement thenSt = SeparateFirstStatement(ref sourceCode);
                        if (thenSt.Type != NULLST)
                        {
                            curSt.Con += thenSt.Con;
                        }
                    }

                    //判断是否含else分支
                    int elseStType = InitType(sourceCode);
                    if (elseStType == ELSE_BR)
                    {
                        CMMStatement elseSt = SeparateFirstStatement(ref sourceCode);
                        curSt.Con += elseSt.Con;
                    }
                    break;
                default: //不会含其他情况,除非出现异常
                    dealError(curSt.Con, "运行出现异常");
                    break;
            }
            return curSt;
        }



        //分析语句元素,并修正语句类型
        public void AnalyzeStatement(ref CMMStatement st)
        {
            st.Con = st.Con.Trim();
            st.Type = InitType(st.Con);
            switch (st.Type)
            {
                case NULLST: //无语句
                case EMPTY:  //空语句
                case ERROR:  //错误语句
                    break;

                case COMPLEX: //复合语句
                    AnalyzeComplex(ref st);
                    break;

                case DECLARE: //声明语句
                    AnalyzeDeclare(ref st);
                    break;

                case INPUT:  //输入语句
                    AnalyzeInput(ref st);
                    break;

                case OUTPUT:  //输出语句
                    AnalyzeOutput(ref st);
                    break;

                case ASSIGN:  //赋值语句
                    AnalyzeAssign(ref st);
                    break;

                case LOOP:   //循环语句
                    AnalyzeLoop(ref st);
                    break;

                case SELECT: //选择语句
                    AnalyzeSelect(ref st);
                    break;

                case ELSE_BR: //if语句的else分支
                    dealError(st.Con, "else语句应紧接if语句then分支后,不可单独使用");
                    break;

                default:
                    break;
            }

        }

        //分析复合语句
        private void AnalyzeComplex(ref CMMStatement st)
        {
            
            string stCon = st.Con;
            if (stCon.EndsWith("}"))
                st.Els[0] = stCon.Substring(1, stCon.Length - 2);
            else
            {
                st.Type = ERROR;
                dealError(st.Con, "缺少'}'");
            }
        }

        //分析声明语句
        private void AnalyzeDeclare(ref CMMStatement st)
        {

            ArrayList stWords = wordAnalysis.GetWordLst(st.Con);

            //声明语句:int|real 标识符;
            if (stWords.Count == 3
                    && wordAnalysis.GetWordType((string)stWords[1]) == ID)
            {
                st.Els[0] = (string)stWords[1];
                st.Els[1] = (string)stWords[0];
                st.Els[2] = NOTARR;
                st.Els[3] = NOTASS;
                return;
            }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -