Khoa Khoa học máy tínhĐỒ ÁN AUTOMAT Viết chương trình phân tích cú pháp, tạo và hiển thị cây cú pháp của một biểu thức chính quy... Phần mở đầu• Mục đích của việc giải quyết bài toán đư
Trang 1Khoa Khoa học máy tính
ĐỒ ÁN AUTOMAT Viết chương trình phân tích cú pháp, tạo và hiển thị
cây cú pháp của một biểu thức chính quy.
MỤC LỤC:
Trang 2Phần mở đầu
Phần I.Cơ sở lí thuyết.
Phần II.Chương trình.
Phần III.Phần code chính của chương trình Phần IV.Tài liệu tham khảo.
Trang 3Phần mở đầu
• Mục đích của việc giải quyết bài toán được giao: Hiểu được định nghĩa về biểu thức chính qui.Phương pháp phân tích biểu thức chính qui
• Để thực hiện đò án Viết chương trình phân tích cú pháp, tạo và hiển thị cây
cú pháp của một biểu thức chính quy ta cần phải:
Thực hiện xử lí chuỗi nhập vào.Xác định xem biểu thức có phải biểu thức chính qui không
Định dạng lại biểu thức
Đưa biểu thức về dạng hậu tố
Biểu diễn biểu thức chính qui dưới dạng cây nhị phân
Phần I.Cơ sở lí thuyết
Trang 4I.Định nghĩa biểu thức chính qui:
Định nghĩa: Biểu thức chính quy được định nghĩa một cách đệ quy như sau:
1 ε là biểu thức chính quy L(ε)={ε}
∅ là biểu thức chính quy L(∅)={∅}
nếu a∈∑, a là biểu thức chính quy L(a)={a}
2 Nếu r, s là các biểu thức chính quy thì:
((r)) là biểu thức chính quy L((r))=L(r);
r+s là biểu thức chính quy L(r+s)=L(r)∪L(s);
r.s là biểu thức chính quy L(r.s)=L(r).L(s);
r* là biểu thức chính quy L(r*)=L(r)*
3 Biểu thức chính quy chỉ định nghĩa như trong 1 và 2
II.Tính chất của biểu thức chính qui:
1.Phép hợp:
• r + ∅ = ∅ + r = r
• r + r = r
• r + s = s + r
• (r + s) + t = r + (s + t) = r + s + t
2.Phép bao đóng:
• e* = e
• ∅* = ∅
• r*r* = r*
• (r*)* = r*
Trang 5• r* = e + r + r2 + … + rk + …
• r* = e + r+
• (e + r)+ = (e + r)* = r*
• r*r = r r* = r+
3 Phép nối kết:
• re = er = r
• r∅ = ∅r = ∅
• (r + s) t = rt + st
• r (s + t) = rs + rt
4 Tổng hợp:
• (r* + s*)* = (r*s*)* = (r + s)*
• (rs)*r = r(sr)*
• (r*s)* r* = (r + s)*
5 Thứ tự ưu tiên của phép toán: * (bao đóng), (phép nối kết), + (phép hợp).
Ví dụ: Biểu thức chính quy cho ngôn ngữ gồm các xâu nhị phân mà không có hai
số 0 hay hai số 1 liên nhau
(01)*+(10)*+0(10)*+1(01)*
hoặc là:
(ε+1)(01)*(ε+0) Thứ tự ưu tiên của phép toán: *, , +
Do đó: 01* + 1 được hiểu như sau: (0(1)*) + 1 (Biểu thức dạng hậu tố)
Trang 6Phần II.Chương trình 1.Cấu trúc chương trình:
Chương trình được viết bằng ngôn ngữ c# trên ứng dụng WindowsForm của chương trình visual studio 2008
Chương trình được viết trên 2 Form, class
frm_KhoiDong:Hiển thị thông tin đồ án
frm_ChuongTrinhChinh:Thực hiện các công việc được phải làm
Các class hỗ trợ cho việc thực hiện chương trình
-KiemTraRE:Kiểm tra biểu thức chính qui nhập vào
-RE:Định dạng biểu thức chính qui và đưa biểu thức chính qui về dạng hậu tố
-State,map,CacLoi,ThongTinBanDau hỗ trợ cho các class KiemTraRE,RE
2.Sơ đồ khối thuật toán:
Nhập vào biểu thức chính qui
True
Đưa về dạng hậu tố Định dạng biểu thức
Trang 73.Giao diện chương trình:
Khởi động
Trang 8Chương trình chính
Trang 9Kết quả
Trang 10Phần III.Phần code chính của chương trình
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using System.IO;
namespace Automata
{
public partial class frm_ChuongTrinhChinh : Form
{
RE BieuThucChinhQui = new RE();
Bitmap NoiVe;
Graphics g;
VeNut[] HinhCay;
Point[] ViTriNut;
Trang 11public frm_ChuongTrinhChinh()
{
InitializeComponent();
ptb_MoPhong.Height = gr_Cay.Height;
ptb_MoPhong.Width = gr_Cay.Width;
KhoiTaoViTri();
NoiVe = new Bitmap(ptb_MoPhong.Width, ptb_MoPhong.Height);
g = Graphics.FromImage(NoiVe);
}
private void KhoiTaoViTri()
{
HinhCay = new VeNut[30];
ViTriNut = new Point[30];
ViTriNut[0] = new Point(238, 31);
for (int i = 0; i < 30; i++)
{
if (i > 0 && i < 3)
{
ViTriNut[i] = new Point(198 + (i - 1) * 79, 91);
}
if(i>2&&i<7)
{
ViTriNut[i] = new Point(198 + (i - 3) * 111, 151);
Trang 12}
if(i>6&&i<15)
{
ViTriNut[i] = new Point(198 + (i - 7) * 49, 211);
}
if (i > 14 && i < 30)
{
ViTriNut[i] = new Point(198 + (i - 15) * 44, 271);
}
}
}
private void btn_Browse_Click(object sender, EventArgs e)
{
OpenFileDialog ofdt = new OpenFileDialog();
ofdt.InitialDirectory = "C:\\";
ofdt.Filter = "All text file(.txt)|*.txt";
if (ofdt.ShowDialog() == DialogResult.OK)
{
FileStream fs = new FileStream(ofdt.FileName, FileMode.Open); StreamReader Sts = new StreamReader(fs);
string tempstr = "";
tempstr = Sts.ReadToEnd();
Sts.Close();
Trang 13fs.Close();
txt_RE.Text = tempstr;
}
}
private void btn_Compile_Click(object sender, EventArgs e)
{
if (txt_RE.Text.Length == 0)
{
MessageBox.Show("Bạn phải nhập vào một Biểu Thức Chính Quy.", "Lỗi!", MessageBoxButtons.OK, MessageBoxIcon.Error);
txt_RE.Select();
return;
}
try
{
CacLoi errCode = BieuThucChinhQui.CompileWithStats(this.txt_RE.Text, txt_RE,txt_BanDau,txt_SauDinhDang,txt_Hauto);
if (errCode != CacLoi.DinhDangDung)
{
string sErrSubstring = txt_RE.Text.Substring(BieuThucChinhQui.GetLastErrorPosition(), BieuThucChinhQui.GetLastErrorLength());
string sFormat = "Phát hiện lỗi khi biên dịch \nMã lỗi : {0}\nTại vị trí thứ : {1}\nKý tự : {2}";
Trang 14sFormat = String.Format(sFormat, errCode.ToString(), BieuThucChinhQui.GetLastErrorPosition(), sErrSubstring); txt_RE.Select(BieuThucChinhQui.GetLastErrorPosition(), BieuThucChinhQui.GetLastErrorLength());
MessageBox.Show(sFormat);
txt_RE.Select();
return;
}
}
catch (Exception ex)
{
MessageBox.Show("Lỗi !!\n\n" + ex.Message);
txt_RE.Select();
return;
}
}
private void btn_Moi_Click(object sender, EventArgs e)
{
txt_RE.Text = "";
txt_BanDau.Text = "";
txt_Hauto.Text = "";
txt_SauDinhDang.Text = "";
}
Trang 15private void gr_Cay_SizeChanged(object sender, EventArgs e) {
ptb_MoPhong.Height = gr_Cay.Height;
ptb_MoPhong.Width = gr_Cay.Width;
}
private bool KiemTraToanTu(string toantu)
{
bool kq;
if (toantu == "." || toantu == "+" || toantu == "*")
kq = true;
else
kq = false;
return kq;
}
private void TaoChiSoThuTu(ref CayNhiPhan CayCanVe) {
if (CayCanVe.ConTrai!=null)
{
CayCanVe.GanThuTuChoConTrai();
TaoChiSoThuTu(ref CayCanVe.ConTrai);
}
if (CayCanVe.ConPhai!=null)
{
Trang 16CayCanVe.GanThuTuChoConPhai();
TaoChiSoThuTu(ref CayCanVe.ConPhai);
}
}
private void TaoThuCacNutCay(CayNhiPhan CayCanVe) {
TaoChiSoThuTu(ref CayCanVe);
GiaTri[0] = CayCanVe.GiaTri;
DuyetHetMang(CayCanVe);
}
string[] GiaTri = new string[30];
CayNhiPhan Phu;
private void ChoVaoMangVe(CayNhiPhan CayCanVe) {
for (int i = 0; i < GiaTri.Length; i++)
{
if (i == CayCanVe.ThuTu)
{
GiaTri[i] = CayCanVe.GiaTri;
break;
}
}
}
Trang 17private void DuyetHetMang(CayNhiPhan CayCanVe) {
if (CayCanVe.ConTrai != null)
{
ChoVaoMangVe(CayCanVe.ConTrai);
DuyetHetMang(CayCanVe.ConTrai);
}
if (CayCanVe.ConPhai != null)
{
ChoVaoMangVe(CayCanVe.ConPhai);
DuyetHetMang(CayCanVe.ConPhai);
}
}
private void bt_Ve_Click(object sender, EventArgs e) {
for (int j = 0; j < GiaTri.Length; j++)
{
GiaTri[j] = "";
}
CayNhiPhan CayCanVe =
CayBieuThuc.HauToVaoCay(txt_Hauto.Text.ToString()); Phu = CayCanVe;
TaoThuCacNutCay(CayCanVe);
Trang 18for (int i = 0; i < GiaTri.Length; i++)
{
if (GiaTri[i] != "")
{
if (GiaTri[i] == "." || GiaTri[i] == "*" || GiaTri[i] == "+")
{
HinhCay[i] = new VeNut(ViTriNut[i].X, ViTriNut[i].Y, GiaTri[i],
"ToanTu");
HinhCay[i].HienThi(g);
if (i != 0)
{
HinhCay[i].NoiNut(HinhCay[(i - 1) / 2], HinhCay[i], g);
}
else
{
}
ptb_MoPhong.Image = NoiVe;
}
else
{
HinhCay[i] = new VeNut(ViTriNut[i].X, ViTriNut[i].Y, GiaTri[i],
"ToanHang");
HinhCay[i].HienThi(g);
Trang 19if (i != 0)
{
HinhCay[i].NoiNut(HinhCay[(i - 1) / 2], HinhCay[i], g); }
else
{
}
ptb_MoPhong.Image = NoiVe;
}
}
}
}
}
}
Trang 20Phần IV.Tài liệu tham khảo.
1.Tài liệu slide bài giảng Automat &NNHT-TS Hà Chí Trung-Bộ môn KHMT-Khoa CNTT- HVKTQS.
2.Code nguồn trên website http://yinyangit.wordpress.com
http://codeproject.com