program
input
output
var
intager
end
begin
and
or
Создание лексического анализатора
При сравнениии например с var или другой маленькой строкой состоящей из трёх или двух символов данные выводятся не правельно.
Скажите пожалуйст, где я ошибся?
Исходные таблицы (они хранятся в текстовых файлах)
1. Ключевые слова
Код:
2. Служебные знаки
Код:
:
,
;
:=
.
>=
<=
(
)
+
-
*
/
,
;
:=
.
>=
<=
(
)
+
-
*
/
3. Другие лексемы
Код:
ivan1
ivan2
x
y
z
ivan2
x
y
z
Исходный код хранится в файлах с расширением (*.SRC)
1. prog1.src
Код:
program ivan2;
z := x + y;
x - y;
ppt >= s : y <= k
z := x + y;
x - y;
ppt >= s : y <= k
Работает правильно
Результат работы
Код:
Анализ строчки: 1
(1,1)
(3,2)
(2,3)
Анализ строчки: 2
(3,5)
(2,4)
(3,3)
(2,10)
(3,4)
(2,3)
Анализ строчки: 3
(3,3)
(2,11)
(3,4)
(2,3)
Анализ строчки: 4
(2,6)
(2,1)
(3,4)
(2,7)
(1,1)
(3,2)
(2,3)
Анализ строчки: 2
(3,5)
(2,4)
(3,3)
(2,10)
(3,4)
(2,3)
Анализ строчки: 3
(3,3)
(2,11)
(3,4)
(2,3)
Анализ строчки: 4
(2,6)
(2,1)
(3,4)
(2,7)
2. prog3.src
Код:
program ivan2;
var;
integer x, y, z;
begin
z := x * y;
end;
var;
integer x, y, z;
begin
z := x * y;
end;
Работает правильно
Результат работы
Код:
Анализ строчки: 1
(1,1)
(3,2)
(2,3)
Анализ строчки: 2
(1,4)
(2,3)
Анализ строчки: 3
(2,2)
(3,4)
(2,2)
(3,5)
(2,3)
Анализ строчки: 4
(1,7)
Анализ строчки: 5
(3,5)
(2,4)
(3,3)
(2,12)
(3,4)
(2,3)
Анализ строчки: 6
(1,6)
(2,3)
(1,1)
(3,2)
(2,3)
Анализ строчки: 2
(1,4)
(2,3)
Анализ строчки: 3
(2,2)
(3,4)
(2,2)
(3,5)
(2,3)
Анализ строчки: 4
(1,7)
Анализ строчки: 5
(3,5)
(2,4)
(3,3)
(2,12)
(3,4)
(2,3)
Анализ строчки: 6
(1,6)
(2,3)
3. prog4.src
Код:
program ivan2;
input
integer x, y, z;
begin
z := x * y;
end;
input
integer x, y, z;
begin
z := x * y;
end;
Работает правильно
Результат работы
Код:
Анализ строчки: 1
(1,1)
(3,2)
(2,3)
Анализ строчки: 2
(1,2)
Анализ строчки: 3
(2,2)
(3,4)
(2,2)
(3,5)
(2,3)
Анализ строчки: 4
(1,7)
Анализ строчки: 5
(3,5)
(2,4)
(3,3)
(2,12)
(3,4)
(2,3)
Анализ строчки: 6
(1,6)
(2,3)
(1,1)
(3,2)
(2,3)
Анализ строчки: 2
(1,2)
Анализ строчки: 3
(2,2)
(3,4)
(2,2)
(3,5)
(2,3)
Анализ строчки: 4
(1,7)
Анализ строчки: 5
(3,5)
(2,4)
(3,3)
(2,12)
(3,4)
(2,3)
Анализ строчки: 6
(1,6)
(2,3)
4. prog2.src
Код:
program ivan2;
var
integer x, y, z;
begin
z := x * y;
end;
var
integer x, y, z;
begin
z := x * y;
end;
Работае неправильно
Результат работы
Код:
Анализ строчки: 1
(1,1)
(3,2)
(2,3)
Анализ строчки: 2
Анализ строчки: 3
(2,2)
(3,4)
(2,2)
(3,5)
(2,3)
Анализ строчки: 4
(1,7)
Анализ строчки: 5
(3,5)
(2,4)
(3,3)
(2,12)
(3,4)
(2,3)
Анализ строчки: 6
(1,6)
(2,3)
(1,1)
(3,2)
(2,3)
Анализ строчки: 2
Анализ строчки: 3
(2,2)
(3,4)
(2,2)
(3,5)
(2,3)
Анализ строчки: 4
(1,7)
Анализ строчки: 5
(3,5)
(2,4)
(3,3)
(2,12)
(3,4)
(2,3)
Анализ строчки: 6
(1,6)
(2,3)
Помогите пожалуйста разобраться?
Вот исходный код
Код:
//------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
StringGrid1->Cells[0][0] = "Номер";
StringGrid1->Cells[1][0] = "Элемент";
StringGrid2->Cells[0][0] = "Номер";
StringGrid2->Cells[1][0] = "Элемент";
StringGrid3->Cells[0][0] = "Номер";
StringGrid3->Cells[1][0] = "Элемент";
}
// Открыть таблицу "ключевых слов"
void __fastcall TForm1::Button1Click(TObject *Sender)
{
if (OpenDialog1->Execute())
{
TStringList *slist = new TStringList();
int j = 0;
slist->LoadFromFile(OpenDialog1->FileName);
for (int i = 1; i <= slist->Count; i++)
{
StringGrid1->Cells[0] = i;
StringGrid1->Cells[1] = slist->Strings[j];
j++;
}
delete slist;
}
}
//------------------------------------------------------------------------
void __fastcall TForm1::Button4Click(TObject *Sender)
{
if (OpenDialog2->Execute())
{
TStringList *slist = new TStringList();
int j = 0;
slist->LoadFromFile(OpenDialog2->FileName);
for (int i = 1; i <= slist->Count; i++)
{
StringGrid2->Cells[0] = i;
StringGrid2->Cells[1] = slist->Strings[j];
j++;
}
delete slist;
}
}
//------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
if (OpenDialog3->Execute())
Memo1->Lines->LoadFromFile(OpenDialog3->FileName);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button5Click(TObject *Sender)
{
if (OpenDialog4->Execute())
{
TStringList *slist = new TStringList();
int j = 0;
slist->LoadFromFile(OpenDialog4->FileName);
for (int i = 1; i <= slist->Count; i++)
{
StringGrid3->Cells[0] = i;
StringGrid3->Cells[1] = slist->Strings[j];
j++;
}
delete slist;
}
}
//------------------------------------------------------------------------
void __fastcall TForm1::Button3Click(TObject *Sender)
{
// Количество итераций в цикле столько, сколько
// строк в исходном коде
for (int i = 0; i < Memo1->Lines->Count; i++)
{//
AnsiString temp = "";
char *tempstr = (Memo1->Lines->Strings).c_str();
Memo2->Lines->Add("Анализ строчки: "+IntToStr(i+1));
// Количестово итераций в цикле столько,
// сколько символов в строке
for (int j = 0; j < (Memo1->Lines->Strings).Length(); j++)
{//2
// Проверяем является ли символ
// буквой или цифрой
if (isalnum(tempstr[j]))
{//3
temp += tempstr[j];
// Проверка символа в таблице "Ключевых слов"
for (int k = 1; k < StringGrid1->RowCount; k++)
{//4
// Находится в таблице "ключевых слов"
if (StringGrid1->Cells[1] [k] == temp)
{//5
Memo2->Lines->Add("(1,"+StringGrid1->Cells[0] [k]+") ");
temp = "";
}//5
}//4
// Проверка символа в таблице "Другие лексемы"
for (int k = 1; k < StringGrid3->RowCount; k++)
{//6
// Находится в таблице "Другие лексемы"
if (StringGrid3->Cells[1] [k] == temp)
{//7
Memo2->Lines->Add("(3,"+StringGrid3->Cells[0] [k]+") ");
temp = "";
}//7
}//6
}//3
else
if (tempstr[j] != ' ')
{//8
temp = "";
temp += tempstr[j];
if ((tempstr[j] == ':' || tempstr[j] == '>' || tempstr[j] == '<') && tempstr[j+1] == '=')
temp += tempstr[j+1];
// Проверка символа в таблице "Служебные знаки"
for (int k = 1; k < StringGrid2->RowCount; k++)
{//9
// Находится в таблице "Служебные знаки"
if (StringGrid2->Cells[1] [k] == temp)
{//10
Memo2->Lines->Add("(2,"+StringGrid2->Cells[0] [k]+") ");
temp = "";
}//10
}//9
temp = "";
}//8
}//2
}//1
}
//-----------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
StringGrid1->Cells[0][0] = "Номер";
StringGrid1->Cells[1][0] = "Элемент";
StringGrid2->Cells[0][0] = "Номер";
StringGrid2->Cells[1][0] = "Элемент";
StringGrid3->Cells[0][0] = "Номер";
StringGrid3->Cells[1][0] = "Элемент";
}
// Открыть таблицу "ключевых слов"
void __fastcall TForm1::Button1Click(TObject *Sender)
{
if (OpenDialog1->Execute())
{
TStringList *slist = new TStringList();
int j = 0;
slist->LoadFromFile(OpenDialog1->FileName);
for (int i = 1; i <= slist->Count; i++)
{
StringGrid1->Cells[0] = i;
StringGrid1->Cells[1] = slist->Strings[j];
j++;
}
delete slist;
}
}
//------------------------------------------------------------------------
void __fastcall TForm1::Button4Click(TObject *Sender)
{
if (OpenDialog2->Execute())
{
TStringList *slist = new TStringList();
int j = 0;
slist->LoadFromFile(OpenDialog2->FileName);
for (int i = 1; i <= slist->Count; i++)
{
StringGrid2->Cells[0] = i;
StringGrid2->Cells[1] = slist->Strings[j];
j++;
}
delete slist;
}
}
//------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
if (OpenDialog3->Execute())
Memo1->Lines->LoadFromFile(OpenDialog3->FileName);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button5Click(TObject *Sender)
{
if (OpenDialog4->Execute())
{
TStringList *slist = new TStringList();
int j = 0;
slist->LoadFromFile(OpenDialog4->FileName);
for (int i = 1; i <= slist->Count; i++)
{
StringGrid3->Cells[0] = i;
StringGrid3->Cells[1] = slist->Strings[j];
j++;
}
delete slist;
}
}
//------------------------------------------------------------------------
void __fastcall TForm1::Button3Click(TObject *Sender)
{
// Количество итераций в цикле столько, сколько
// строк в исходном коде
for (int i = 0; i < Memo1->Lines->Count; i++)
{//
AnsiString temp = "";
char *tempstr = (Memo1->Lines->Strings).c_str();
Memo2->Lines->Add("Анализ строчки: "+IntToStr(i+1));
// Количестово итераций в цикле столько,
// сколько символов в строке
for (int j = 0; j < (Memo1->Lines->Strings).Length(); j++)
{//2
// Проверяем является ли символ
// буквой или цифрой
if (isalnum(tempstr[j]))
{//3
temp += tempstr[j];
// Проверка символа в таблице "Ключевых слов"
for (int k = 1; k < StringGrid1->RowCount; k++)
{//4
// Находится в таблице "ключевых слов"
if (StringGrid1->Cells[1] [k] == temp)
{//5
Memo2->Lines->Add("(1,"+StringGrid1->Cells[0] [k]+") ");
temp = "";
}//5
}//4
// Проверка символа в таблице "Другие лексемы"
for (int k = 1; k < StringGrid3->RowCount; k++)
{//6
// Находится в таблице "Другие лексемы"
if (StringGrid3->Cells[1] [k] == temp)
{//7
Memo2->Lines->Add("(3,"+StringGrid3->Cells[0] [k]+") ");
temp = "";
}//7
}//6
}//3
else
if (tempstr[j] != ' ')
{//8
temp = "";
temp += tempstr[j];
if ((tempstr[j] == ':' || tempstr[j] == '>' || tempstr[j] == '<') && tempstr[j+1] == '=')
temp += tempstr[j+1];
// Проверка символа в таблице "Служебные знаки"
for (int k = 1; k < StringGrid2->RowCount; k++)
{//9
// Находится в таблице "Служебные знаки"
if (StringGrid2->Cells[1] [k] == temp)
{//10
Memo2->Lines->Add("(2,"+StringGrid2->Cells[0] [k]+") ");
temp = "";
}//10
}//9
temp = "";
}//8
}//2
}//1
}
//-----------------------------------------------------------------------
Попробовал вывести в Memo
Там когда анализируется строка var буква "a" вообще прободает.
И ещё не соединяются символы.
То есть получается так в Memo
v
r
А должно быть
v
va
var
когда в место var сравниваешь например input всё нормально.
В чём же дело, помогите пожалуйста?
char *tempstr = (Memo1->Lines->Strings).c_str();
При работе со списками из других контролов ВСЕГДА создавайте локальную копию:
AnsiString S = Memo1->Lines->Strings;
char *tempstr = S.c_str();
// зачем было указатель вытаскивать - есть же S
===================================
Попутно:
зачем вам 4 (!!!) OpenDialog-а? Чтоб были? Достаточно одного.
код из конструктора убрать - перенесите его в OnCreate
лишний счетчик при загрузке, вполне пойдет:
for (int i = 1; i <= List->Count; i++)
{
StringGrid1->Cells[0] = i;
StringGrid1->Cells[1] = List->Strings[i - 1];
}
Всё заработало.
Вопрос решён.
Только хотелось бы уточнить одну вещь
Почему надо всегда созавать локальную переменную или где об этом можно почитать.
а создавать копию надо потому что строка возвращается в стеке, и c_str возвращает адрес в стеке, и естественно первый вызов любой функции вашу строку уничтожит. прикол от борланда :)
Большое спасибо за пояснение
Цитата: Zor
Код:
char *tempstr = S.c_str();
Это пример, как делать не надо. И это уже не раз обсуждалось.
пока нормально. потом дозреет до S[Index] :)
За 2 прохода розбивает исходник на лексемы и проверяет синтаксис. Пропускает почти все валидные коды. Точно не пропустит writeln(i[COLOR=Red]:10[/COLOR]) и еще помоему в синтаксисе классов была какаято недороботка.