Консультация № 184069
23.09.2011, 14:28
0.00 руб.
0 3 1
Здравствуйте уважаемы эксперты. Прошу написать программу по С++.
Вот задание:
Построить синтаксический анализатор для понятия скобки.
скобки ::=квадратные|круглые|фигурные
квадратные ::=[круглые фигурные]|+
круглые::=(фигурные квадратные)|-
фигурные::={квадратные круглые}|0

заранее благодарен

Обсуждение

давно
Профессор
230118
3054
23.09.2011, 15:08
общий
+ Тоже считается квадратной скобкой?
Неизвестный
24.09.2011, 15:45
общий
| это или
так что да
Неизвестный
28.09.2011, 15:08
общий
это ответ
Здравствуйте, Посетитель - 381415!
Предлагаю вариант с использованием конечного автомата.
Составим таблицу состояний. По строкам - состояние системы (в нашем случае, предыдущий найденный символ), по столбцам - все возможные символы (заданные грамматикой плюс один столбец под все остальные).
[table]
[row][col #708090][/col][col #708090])[/col][col #708090]([/col][col #708090]}[/col][col #708090]{[/col][col #708090][[/col][col #708090]][/col][col #708090]+[/col][col #708090]-[/col][col #708090]0[/col][col #708090]конец строки[/col][col #708090]другое[/col][/row]
[row][col #708090]начало строки[/col][col #9c183f]ошибка[/col][col]1[/col][col #9c183f]ошибка [/col][col] 2[/col][col]3 [/col][col #9c183f] ошибка[/col][col]4 [/col][col]5 [/col][col]6 [/col][col #3caa3c] успех[/col][col #9c183f]ошибка [/col][/row]
[row][col #708090]([/col][col #9c183f]ошибка [/col][col #9c183f]ошибка [/col][col #9c183f]ошибка [/col][col]2[/col][col #9c183f]ошибка [/col][col #9c183f]ошибка [/col][col #9c183f]ошибка [/col][col #9c183f]ошибка [/col][col]6 [/col][col #9c183f]ошибка [/col][col #9c183f]ошибка [/col][/row]
[row][col #708090]{[/col][col #9c183f]ошибка[/col][col #9c183f]ошибка [/col][col #9c183f]ошибка [/col][col #9c183f]ошибка [/col][col]3 [/col][col #9c183f]ошибка [/col][col]4 [/col][col #9c183f]ошибка [/col][col #9c183f]ошибка [/col][col #9c183f]ошибка [/col][col #9c183f]ошибка [/col][/row]
[row][col #708090][[/col][col #9c183f]ошибка [/col][col] 1[/col][col #9c183f] ошибка[/col][col #9c183f]ошибка [/col][col #9c183f]ошибка [/col][col #9c183f]ошибка [/col][col #9c183f]ошибка [/col][col] 5[/col][col #9c183f]ошибка [/col][col #9c183f]ошибка [/col][col #9c183f]ошибка [/col][/row]
[row][col #708090]+[/col][col]5 [/col][col]1 [/col][col #9c183f]ошибка [/col][col #9c183f]ошибка [/col][col #9c183f] ошибка[/col][col #9c183f]ошибка [/col][col #9c183f]ошибка [/col][col]5 [/col][col #9c183f]ошибка [/col][col #3caa3c]успех [/col][col #9c183f]ошибка [/col][/row]
[row][col #708090]-[/col][col #9c183f]ошибка [/col][col #9c183f]ошибка [/col][col]6 [/col][col]2 [/col][col #9c183f] ошибка[/col][col #9c183f]ошибка [/col][col #9c183f]ошибка [/col][col #9c183f]ошибка [/col][col]6[/col][col #3caa3c]успех [/col][col #9c183f]ошибка [/col][/row]
[row][col #708090]0[/col][col #9c183f]ошибка [/col][col #9c183f]ошибка [/col][col #9c183f]ошибка [/col][col #9c183f]ошибка [/col][col]3 [/col][col]4 [/col][col]4 [/col][col #9c183f]ошибка [/col][col #9c183f]ошибка [/col][col #3caa3c]успех [/col][col #9c183f]ошибка [/col][/row]
[/table]
В ячейках прописывам следующее состояние, т.е. в данном случае это будет номер строки. Алгоритм составления такой таблицы прост: сначала рассматриваем состояние "начало строки" и прописываем переходы. Если символ в текущем состоянии допустим, то выделяем для него строку (ставим незадействованный номер строки), если нет - ошибка. Далее все созданные на первом этапе состояния надо расписать аналогично, каждое на новой строке. В процессе могут возникнуть новые состояния, их тоже надо учитывать.
Задание я поняла так:
Корректные записи:
[-0]
[(0+){+-}]
+
Некорректные:
()
{[]()}
В приложении - программа, реализующая данный алгоритм. Проверено в Visual Studio 2005.
Удачи!

Приложение:
#include <iostream>
using namespace std;

//таблица состояний
const int err = 12;
const int success = 13;
const int avt [7][11] = {
{err, 1, err, 2, 3, err, 4, 5, 6, success, err},
{err, err, err, 2, err, err, err, err, 6, err, err},
{err, err, err, err, 3, err, 4, err, err, err, err},
{err, 1, err, err, err, err, err, 5, err, err, err},
{5, 1, err, err, err, err, err, 5, err, success, err},
{err, err, 6, 2, err, err, err, err, 6, success, err},
{err, err, err, err, 3, 4, 4, err, err, success, err}};

int get_col (char c) //функция перехода на столбец соответственно символу
{
switch (c) {
case ')':
return 0;
case '(':
return 1;
case '}':
return 2;
case '{':
return 3;
case '[':
return 4;
case ']':
return 5;
case '+':
return 6;
case '-':
return 7;
case '0':
return 8;
case '\0':
return 9;
default:
return 10;
}
}

bool check (char* str) //функция проверки
{
int st = 0;
int len = strlen(str);

for (int i = 0; i <= len; i++) //идём по строке до \0 включительно
{
st = avt[st][get_col(str[i])]; //получаем новое состояние из таблицы
if (st == err) //если ошибка - возвращаем её
return false;
else if (st == success) //если успех - возвращаем его
return true;
}//если иное значение состояния - переходим на следующую итерацию

return false; //сюда попасть по идее никогда не должны
}

int main ()
{
char buf[256];
while (true) {
cout << "\nEnter: ";
cin >> buf;
if (check (buf)) cout << "\nOk";
else cout << "\nBad";
}
return 0;
}
Форма ответа