WPF外观词法分析器
2010-01-05 17:13 花晓霜 阅读(602) 评论(0) 编辑 收藏 举报写这个词法分析器,我主要是利用基于.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'; } } }
项目工程截图如下:
运行截图如下: