Синтаксический анализатор (проверка на наличие русских букв) - C#
Формулировка задачи:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
namespace scaner
{
public partial class Form1 : Form
{
List<int> lst = new List<int>();
int position = 0;
List<string> key_table = new List<string>();
List<string> var_table = new List<string>();
List<int> const_table = new List<int>();
List<string> termin_table = new List<string>();
List<res> result_scanned = new List<res>();
string buffer = "";
string s = "";
int prev_pos = 0;
bool flagok = false;
public class res
{
public res(int a, int b)
{
t = a;
pos = b;
}
public int t;
public int pos;
}
public Form1()
{
InitializeComponent();
tabl_key_termin_entering();
}
void tabl_key_termin_entering()
{
// string slovo;
//int index = key_table.IndexOf(slovo);
key_table.Add("program");
key_table.Add("var");
key_table.Add("begin");
key_table.Add("end");
key_table.Add("procedure");
key_table.Add("while");
key_table.Add("do");
key_table.Add("for");
key_table.Add("writeln"); key_table.Add("write");
key_table.Add("readln"); key_table.Add("read");
key_table.Add("integer");
key_table.Add("real");
key_table.Add("function");
termin_table.Add("(");
termin_table.Add(")");
termin_table.Add(";");
termin_table.Add(":="); termin_table.Add(":");
termin_table.Add(" ");
termin_table.Add("=");
termin_table.Add("+");
termin_table.Add("-");
termin_table.Add("<="); termin_table.Add("<");
termin_table.Add(">="); termin_table.Add(">");
termin_table.Add("\r");
termin_table.Add("\n");
termin_table.Add(".");
termin_table.Add(",");
}
private void button3_Click(object sender, EventArgs e)
{
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
FileStream fs = File.OpenRead(openFileDialog1.FileName);
UTF8Encoding ue = new UTF8Encoding();
byte[] bytes = new byte[fs.Length];
fs.Read(bytes, 0, (int)fs.Length);
s = ue.GetString(bytes);
s = s.ToLower();
richTextBox2.Text = s.ToString();
}
}
public void Laba1()
{
bool flag = false;
// if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
/* FileStream fs = File.OpenRead(openFileDialog1.FileName);
UTF8Encoding ue = new UTF8Encoding();
byte[] bytes = new byte[fs.Length];
fs.Read(bytes, 0, (int)fs.Length);
s = ue.GetString(bytes);
s = s.ToLower();*/
s = richTextBox2.Text;
result_scanned.Clear();
var_table.Clear();
const_table.Clear();
for (int i = 0; i < s.Length; i++)
{
//проверка на терминальный символ
for (int j = 0; j < termin_table.Count; j++)
{
position = 0;
string kk = "";
if (termin_table[j].Length <= s.Length - i)
for (int jj = i; jj < i + termin_table[j].Length; jj++)
kk += s[jj];
if (kk == termin_table[j])
{
position = i + termin_table[j].Length;
result_scanned.Add(new res(4, j));
if (flag) prev_pos = position;
flag = true;
break;
}
}
if (flag == false) buffer += s[i];
//esli nashli
if (flag && buffer != "")
{
flag = false;
// проход по таблицам
// if (prev_pos != -1)
// {
// string tmp = "";
// for (int jj = prev_pos; jj < i; jj++)
// tmp += s[jj];
//с ключевыми
for (int jj = 0; jj < key_table.Count; jj++)
if (buffer == key_table[jj])
{
if (buffer == "var") flagok = true;
if (buffer == "real") flagok = false;
result_scanned.Insert(result_scanned.Count - 1, new res(1, jj));
buffer = "";
goto ex;
}
//c константами
try
{
int chislo = Convert.ToInt32(buffer);
if (const_table.Contains(chislo))
{ }
else
{ const_table.Add(chislo);}
result_scanned.Insert(result_scanned.Count - 1, new res(3, (int)const_table.IndexOf(chislo)));
}
catch (Exception)
{
//переменные
if (var_table.Contains(buffer))
{ }
else
{
var_table.Add(buffer);
if (flagok) lst.Add((int)var_table.IndexOf(buffer));
if (buffer[0].ToString() == "'") lst.Add((int)var_table.IndexOf(buffer));
}
result_scanned.Insert(result_scanned.Count - 1, new res(2, (int)var_table.IndexOf(buffer)));
}
// }
// else
prev_pos = position;
buffer = "";
}
ex:
// считываем символ, буфер
// если он терминальный - считываем лексему
//и заносим или нет в таблицу, отмечаем в результе
//пометки терминалов и лексем
//проверка не лексемы
flag = false;
}
}
//string[] lines = s.Split("\r\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
}
private void button1_Click(object sender, EventArgs e)
{
}
private void button2_Click(object sender, EventArgs e)
{
//if (openFileDialog1.ShowDialog() == DialogResult.OK)
Laba1();
//richTextBox2.Text = s.ToString();
textBox1.Text = "";
List<string> resultat = new List<string>();
//Proramm
if (result_scanned[0].pos == 0 && result_scanned[0].t == 1)
{ /*textBox1.Text += "= - )) Ошибок в терминале Proramm нет!!! \r\n*********************************************************************\r\n"; */}//
else { textBox1.Text += " Отсутствует programm \n"; };
//имя
if (result_scanned[2].t == 2)
{ /*textBox1.Text += "= - )) Ошибок в имени нет!!! \r\n*********************************************************************\r\n"; */}
else { textBox1.Text += " Uncorrected name of program \n"; };
////Проверка парности (-)
{
int open = 0; int close = 0;
for (int i = 0; i < result_scanned.Count; i++)
{
if (result_scanned[i].t == 4 && result_scanned[i].pos == 0)
{ open++; }
}
for (int i = 0; i < result_scanned.Count; i++)
{
if (result_scanned[i].t == 4 && result_scanned[i].pos == 1)
{ close++; }
}
for (int i = 0; i < result_scanned.Count; i++)
{
if ((result_scanned[i].t == 4 && result_scanned[i].pos == 0) && (result_scanned[i + 1].t == 4 && result_scanned[i + 1].pos == 1))
textBox1.Text += "Пустые скобки\n";
}
if (open > close)
{ textBox1.Text += " Пропущены закрывающиеся скобки \n"; };
if (open < close)
{ textBox1.Text += " Пропущены открывающиеся скобки \n"; }
else { /*textBox1.Text += "= - )) Скобки в порядке\r\n*********************************************************************\r\n"; */};
}
//Проверка парности begin-end
{
int begin = 0; int end = 0;
for (int i = 0; i < result_scanned.Count; i++)
{
if (result_scanned[i].t == 1 && result_scanned[i].pos == 2)
{ begin++; }
}
for (int i = 0; i < result_scanned.Count; i++)
{
if (result_scanned[i].t == 1 && result_scanned[i].pos == 3)
{ end++; }
}
if (begin > end)
{ textBox1.Text += " ( Пропущен end \n"; };
if (begin < end)
{ textBox1.Text += " ( Пропущен begin \n"; }
else { /*textBox1.Text += "= - )) begin-end в порядке\r\n*********************************************************************\r\n"; */};
}
//проверка Writeln/write+Readln/read
{
for (int i = 0; i < result_scanned.Count; i++)
{
if (result_scanned[i].t == 1 && (result_scanned[i].pos == 8 || result_scanned[i].pos == 9))
{
if (result_scanned[i + 1].t == 4 && result_scanned[i+1].pos == 0)
{ }
else { textBox1.Text += " После writeln/write нет терминального символа \n"; };
}
}
for (int i = 0; i < result_scanned.Count; i++)
{
if (result_scanned[i].t == 1 && (result_scanned[i].pos == 10 || result_scanned[i].pos == 11))
{
if (result_scanned[i + 1].t == 4 && result_scanned[i+1].pos == 0)
{ }
else { textBox1.Text += " После Readln/read нет терминального символа \n"; };
}
}
}
//проверка ;
for (int i = 0; i < result_scanned.Count; i++)
{
if (result_scanned[i].t == 4 && result_scanned[i].pos == 2)
{
if (result_scanned[i + 1].t == 4 && result_scanned[i + 1].pos == 14)/*13*/
{ /*textBox1.Text += "= - )) С ; все впорядке \r\n*********************************************************************\r\n"; */ }
else { textBox1.Text += " Некорректно использована ; \n"; };
}
}
//проверка var Begin
for (int i = 0; i < result_scanned.Count; i++)
{
if (result_scanned[i].t == 1 && result_scanned[i].pos == 1)
{
if ((result_scanned[i + 1].t == 4 && result_scanned[i + 1].pos == 14)/*13*/ && (result_scanned[i - 1].t == 4 && result_scanned[i - 1].pos == 14))
{ /*textBox1.Text += "= - )) С Var все впорядке \r\n*********************************************************************\r\n"; */}
else { textBox1.Text += " Лишний контекст в строке с Var \n"; };
}
if (result_scanned[i].t == 1 && result_scanned[i].pos == 2)
{
if ((result_scanned[i + 1].t == 4 && result_scanned[i + 1].pos == 14)/*13*/ && (result_scanned[i - 1].t == 4 && result_scanned[i - 1].pos == 14))
{ /*textBox1.Text += "= - )) С Begin все впорядке \r\n*********************************************************************\r\n"; */}
else { textBox1.Text += " Лишний контекст в строке с Begin \n"; };
}
}
//проверка Перед точкой только END
for (int i = 0; i < result_scanned.Count; i++)
{
if (result_scanned[i].t == 4 && result_scanned[i].pos == 15)
{
if (result_scanned[i - 1].t == 1 && result_scanned[i - 1].pos == 3)
{ /*textBox1.Text += "= - )) С точкой все впорядке \r\n*********************************************************************\r\n"; */}
else { textBox1.Text += " Не правильно поставлена точка \n"; };
}
}
//проверка наличия ; или . после END
for (int i = 0; i < result_scanned.Count; i++)
{
if (result_scanned[i].t == 1 && result_scanned[i].pos == 3)
{
if ((result_scanned[i + 1].t == 4 && result_scanned[i + 1].pos == 2) || (result_scanned[i + 1].t == 4 && result_scanned[i + 1].pos == 15))
{ /*textBox1.Text += "= - )) После End все впорядке \r\n*********************************************************************\r\n"; */}
else { textBox1.Text += " Ошибка конструкции \n"; };
}
}
for (int i = result_scanned.Count - 1; i > 0; i--)
{
if (result_scanned[i].t == 2 && !lst.Contains(result_scanned[i].pos) )
{
if (result_scanned[i].pos != 0) textBox1.Text += " Не существует переменной \n";
}
}
//проверка последнего END на точкой
int i_nado = 0;
for (int i = result_scanned.Count-1; i > 0; i--)
{
if (result_scanned[i].t == 1 && result_scanned[i].pos == 3)
{
i_nado = i;
if (result_scanned[i + 1].t == 4 && result_scanned[i + 1].pos == 15)
{ /*textBox1.Text += "= - )) Последний End с точкой \r\n*********************************************************************\r\n"; */}
else { textBox1.Text += " Пропущена точка после end \n"; };
break;
}
}
//проверка предыдущих END на ;
for (int i = i_nado - 1; i > 0; i--)
{
if (result_scanned[i].t == 1 && result_scanned[i].pos == 3)
{
i_nado = i;
if (result_scanned[i + 1].t == 4 && result_scanned[i + 1].pos == 2)
{ /*textBox1.Text += "= - )) предыдущие End с ; \r\n*********************************************************************\r\n"; */}
else { textBox1.Text += " Пропущена; после end \n"; };
}
}
//проверка +-
for (int i = 0; i < result_scanned.Count; i++)
{
if (result_scanned[i].t == 4 && (result_scanned[i].pos == 7 || result_scanned[i].pos == 8))
{
if (result_scanned[i + 1].t == 2 || result_scanned[i + 1].t == 3) { }else
if ((result_scanned[i].pos == 8||result_scanned[i].pos==7) && result_scanned[i].t == 1 && (result_scanned[i + 1].t == 3 || result_scanned[i + 1].t == 2)||(result_scanned[i+1].t==4&&result_scanned[i+1].pos==0)) { }
else
if ((result_scanned[i + 1].t == 2 || result_scanned[i + 1].t == 3 || (result_scanned[i + 1].t == 4 && result_scanned[i + 1].pos == 0)) && (result_scanned[i - 1].t == 2 || result_scanned[i - 1].t == 3 || (result_scanned[i - 1].t == 4 && result_scanned[i - 1].pos == 1)))
{ /*textBox1.Text += "вокруг + или - все хорошо \r\n"; */}
else { textBox1.Text += "Неправильное арифметическое выражение\n"; };
}
}
if (textBox1.Text == "") { textBox1.Text = "Программа без ошибок"; }
}
private void richTextBox2_TextChanged(object sender, EventArgs e)
{
}
private void Form1_Load(object sender, EventArgs e)
{
}
}
}Решение задачи: «Синтаксический анализатор (проверка на наличие русских букв)»
textual
Листинг программы
// первый способ проверять регуляркой
Regex reg = new Regex(@"^([^а-яА-Я]+)$");
if (! reg.IsMatch("Hello Мир !!!"))
Console.WriteLine("В строке присутствуют кириллические символы.");
else
Console.WriteLine("Строка без кириллицы.");
// второй способ проверять методом IndexOfAny объекта string
string str = "Hello World !!!";
string chs = "йцукенгшщзхъфывапролджэячсмитьбюЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ";
if(str.IndexOfAny(chs.ToCharArray()) != -1)
Console.WriteLine("В строке присутствуют кириллические символы.");
else
Console.WriteLine("Строка без кириллицы.");