WPF外观词法分析器

写这个词法分析器,我主要是利用基于.NET 3.0的WPF来实现的界面的,通过一个自己写的analyser的类来实现词法分析的主要过程。
我在WPF的界面放置两个Textbox把他们的wrap属性置为True,然后第一个文本框里输入原始字符串,我在放置一个button,通过调用button的点击事件来实现将原字符串经过analyser的analyse方法返回的字符串从第二个textbox输出。
在analyse类中我用一个二维数组来存储特殊字符的信息,大致分为四类:数字,关键字,数学运算符和关系运算法,其余的非数字字符置为标示符。然后我用7个状态来区分他们,用一个叫currencyStatus储存状态。这些状态分别是:A.初始状态 B.转到界符状态 C.转到算术运算符状态 D.转到比较运算符状态 E.转到数字状态 F.转到字符状态 G.结束

具体代码如下:

1. WPF界面的XAML代码如下:

Window1.xaml文件:

<Window x:Class="Jeramine.WPF.Lexer.Window1"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    Title="Jeramine.WPF.Lexer" Height="300" Width="690">

    <Grid>

        <!--author by Jermaine-->

        <TextBox HorizontalAlignment="Left" Margin="12,12,0,12" Name="txtInit" Width="270" TextWrapping="Wrap" />

        <TextBox HorizontalAlignment="Right" Margin="0,12,12,12" Name="txtAnalysis" Width="270" TextWrapping="Wrap" />

        <Button Height="23" Margin="296,27,295,0" Name="btnAnlyze" VerticalAlignment="Top" Content="分析" Click="btnAnlyze_Click"></Button>

    </Grid>

</Window>

2. 后台的cs代码如下,它通过一个button的点击事件来实现把原文本框里面的文本经过词法分析analyse类解析出来各个符号的作用。

/**Main WPF Window 逻辑代码

 *author by Jermaine 

 */

namespace Jeramine.WPF.Lexer

{

    /// <summary>

    /// Window1.xaml 的交互逻辑

    /// </summary>

    public partial class Window1 : Window

    {

        public Window1()

        {

            InitializeComponent();

        }



        private void btnAnlyze_Click(object sender, RoutedEventArgs e)

        {

            Analyser ansr = new Analyser();

            txtAnalysis.Text = ansr.Analyse(txtInit.Text).ToString();

        }

    }

}

3. 词法解析核心类analyser,主要包含了两个方法,analyse和checkletter,主要逻辑是通过在analyse方法中调用checkletter方法来区分字符是属于哪一种状态的,然后在analyse中实现各种类型的区分

Analyser.cs文件:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.IO;

/**主要分析程序

 * author by Jermaine

 */

namespace Jeramine.WPF.Lexer

{

     public  class Analyser

    {

         /*定义各种符号的数组和状态*/

         const int KeyNum = 4;

         public static string[][] key = new string[KeyNum][];

         static char currencyStatus;//用来存储状态



         /*

         状态表

         * A 初始状态

         * B 转到界符状态

         * C 转到算术运算符状态

         * D 转到比较运算符状态

         * E 转到数字状态

         * F 转到字符状态

         * G over

        */



         /*类型表

          * 关键字 0

          * 界符 1

          * 算术运算符 2 

          * 关系运算符   3

          * 标识符   4

          * 数字 5

         */

        /// <summary>

        ///

        /// </summary>

        /// <param name="source">原始文本</param>

        /// <returns>格式化文本</returns>

        public StringBuilder Analyse(string source)

        {

            StringBuilder destiny = new StringBuilder();

            //数组定义,除此之外字母为标示符

            key[0] = new string[] { "while", "if", "for", "int", "main" };//关键字

            key[1] = new string[] { ",", ";", "(", ")", "{", "}" };//界符

            key[2] = new string[] { "=", "*", "+", "/", "-", "++","--"};//算术运算符

            key[3] = new string[] { ">", ">=", "==", "<=", "<" };//关系运算符



            StringReader str = new StringReader(source);//以流的方式读出字符串

            string sen = String.Empty;

            string word = String.Empty;//用来截取字符串

            while ((sen = str.ReadLine()) != null)

             {

                 sen = sen + '\0';

                 currencyStatus = 'A';

                 for (int i = 0; i < sen.Length; i++)

                 {

                     char newStatus;

                     newStatus = CheckLetter(sen[i], currencyStatus);

                     if (newStatus != currencyStatus)

                     {

                         if (currencyStatus == 'F')

                         {

                             int flag = 1;//关键字和标识符的标志

                             for (int j = 0; j < key[0].Length; j++)

                             {

                                 if (word.ToString() == key[0][j].ToString())

                                 {

                                     destiny.Append(word + "是关键字\n");

                                     flag = 0;

                                     break;

                                 }

                               

                             }

                             if (flag == 1)

                             {

                                 destiny.Append(word + " 是标识符\n");

                             }

                         }

                         

                         else if (currencyStatus == 'B')

                         {

                             foreach (char a in word)

                             {

                                 for (int j = 0; j < key[1].Length; j++)

                                 {

                                     if (a.ToString() == key[1][j].ToString())

                                     {

                                        destiny.Append(a.ToString() + " 是界符\n");

                                         break;

                                     }

                                 }

                             }

                         }



                           else if (currencyStatus == 'C')

                        {

                            for (int j = 0; j < key[2].Length; j++)

                            {

                                if (word.ToString() == key[2][j].ToString())

                                {

                                   destiny.Append(word + "是算术运算符\n");

                                    break;

                                }

                            }

                        }



                        else if (currencyStatus == 'D')

                        {

                            for (int j = 0; j < key[3].Length; j++)

                            {

                                if (word.ToString() == key[3][j].ToString())

                                {

                                    destiny.Append(word + " 是关系运算符\n");

                                    break;

                                }

                            }

                        }



                        else if (currencyStatus == 'E')

                        {

                           destiny.Append(word + " 是数字\n");

 

                        }

                        word = sen[i].ToString().Trim();



                    }

                    else

                    {

                        word = word + sen[i].ToString().Trim();

                    }

                     currencyStatus = newStatus;

                 }

             }

            return destiny;

        }

         /// <summary>

         /// 

         /// </summary>

         /// <param name="letter"></param>

         /// <param name="currencyStatus"></param>

         /// <returns></returns>

        static char CheckLetter(char letter, char currencyStatus)

        {

            //跳转 or 保持 字符状态

            if (char.IsLetter(letter) == true)

                return 'F';

            else if (char.IsNumber(letter) == true && currencyStatus == 'F')

                return 'F';

            //跳转 or 保持 数字状态

            else if (char.IsNumber(letter) == true)

                return 'E';

            //界符

            else if (letter == ',' || letter == ';' || letter == '(' || letter == ')' || letter == '{' || letter == '}' || letter == '[' || letter == ']')

                return 'B';

            //算术运算符

            else if (letter == '*' || letter == '+' || letter == '-' || letter == '/')

                return 'C';

            //比较运算符

            else if (letter == '=' || letter == '>' || letter == '<')

                return 'D';

            //结束

            else return 'G';

        }

    }

}

项目工程截图如下:

clip_image002

运行截图如下:

clip_image004

你可能感兴趣的:(WPF)