Проверка семантики кода

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Проверка семантики кода

Сообщение jangle » 12.04.2012 (Чт) 10:52

Пытаюсь реализовать семантическую проверку бейсик кода. Допустим есть такой код

Код: Выделить всё
sub main()
Msgbox Hello
end sub

function Hello() as string
function="Hello World"
end function


Лексический анализатор строит по нему таблицу. Где первый столбец - токен, второй - класс токена, третий - ID класса.
На самом деле столбцов больше, там еще хранится строка и позиция в которой лежит токен в исходнике.

Код: Выделить всё
sub  -    IDENT -  8
main  -    IDENT -  1
(   -   LPARM -  4
)   -   RPARM  - 5
    -  EOL -  10
Msgbox -    IDENT  - 1
Hello -  String -  1
   -   EOL -  10
end  -   IDENT -  8
sub  -   IDENT -   8
-     EOL -  10
-     EOL -  10
function  -    IDENT -  1
Hello   -   String -  1
(  -    LPARM  - 4
)  -    RPARM  - 5
as  -    IDENT -  1
string  -    IDENT -  1
  -    EOL -  10
function  -    IDENT - 1
=    -  Delimiter -  9
Hello World   -   Quote_String -  3
-     EOL -  10
end  -    IDENT -  8
function  -    IDENT  -1
-     EOL -  10
  -    EOP -  11


Эта таблица является источником данных для семантического анализатора. Допустим он читает токены в буфер начиная с первого и до тех пор пока не попадется EOL. Получается
Код: Выделить всё
IDENT,  IDENT, LPARM , RPARM , EOL

Дальше необходима проверка этого кода. Пока ничего кроме таблицы "с правилами" в голову не приходит. Проблема в том, что в таблице получается слишком много вариантов правил, и все их описать невозможно. Например анализатор пойдет дальше и прочитает
Код: Выделить всё
Msgbox - IDENT, Hello  - String ,  EOL
и сразу обломается на Hello, потому как у него нет никакой информации что это такое. Переменная? Константа? Функция? А ведь там еще может быть выражение любой сложности. Поэтому вариант с правилами в таблице как-то не катит. Нужен правильный алгоритм. Только вот какой?

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Re: Проверка семантики кода

Сообщение jangle » 12.04.2012 (Чт) 16:14

Забавно, но когда вдумаешься в задачу, оказывается необходимо иметь кучу таблиц.
-Таблица лексем
-Таблица переменных (Название, Массив?, Размерность, Тип, ОбластьВидимости)
-Таблица констант (Название, Тип)
-Таблица меток (Название, Позиция,ОбластьВидимости )
-Таблица функций (Название, ВходныеПараметры, ВозвращаемыйПараметр)
и т.д.

Причем все таблицы связаны. Таблица функций с Таблицей переменных и Таблицей меток.
Это же база данных! Наверное еще никому не приходило в голову, делать парсинг в базу данных вместо построения дерева зависимостей. Похоже главный минус, это слишком медленно будет работать

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Проверка семантики кода

Сообщение Хакер » 12.04.2012 (Чт) 16:37

jangle писал(а):Поэтому вариант с правилами в таблице как-то не катит.

Катит. Не с правилами в таблице, а с правилами в графе.

Для получения токенов из потока символов граф примерно такой:
Изображение

jangle писал(а):и сразу обломается на Hello, потому как у него нет никакой информации что это такое. Переменная? Константа? Функция? А ведь там еще может быть выражение любой сложности.

Не облом. Обработка должна делать послойно. Конвейером. Один блок конвертирует последовательность символов в последовательность токенов. На входе — поток символов, на выходе — поток токенов. Второй блок конвертирует поток токенов в другой чуть изменённый поток токенов, например один и тот же токен (T_NAME) заменяет на два: T_KEYWORD и T_IDENTIFIER — в зависимости от того, является ли репрезентируемая ею подстрока ключевым словом языка.
И так далее — одну последовательность в другую более сложную последовательность.

Не нужно стремиться сделать один-монолитный-мега-компонент, который из потока символов сразу сделает дерево, полностью репрезентирующее код. Надо мелкими шажками, послойно, идти к цели — глаза боятся, а руки делают.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Re: Проверка семантики кода

Сообщение jangle » 12.04.2012 (Чт) 17:06

Хакер писал(а):Катит. Не с правилами в таблице, а с правилами в графе.


А какой вид эти правила в графе имеют в vb-коде? Это какой-то набор SELECT-CASE`ов?

Не облом. Обработка должна делать послойно. Конвейером. Один блок конвертирует последовательность символов в последовательность токенов. На входе — поток символов, на выходе — поток токенов. Второй блок конвертирует поток токенов в другой чуть изменённый поток токенов, например один и тот же токен (T_NAME) заменяет на два: T_KEYWORD и T_IDENTIFIER — в зависимости от того, является ли репрезентируемая ею подстрока ключевым словом языка.
И так далее — одну последовательность в другую более сложную последовательность.


Даже если и послойно. Если встречается неизвестная лексема, например имя функции которая встретится значительно позднее в коде, или не встретится. По идее сканер должен генерировать ошибку, он же не может "заглянуть вперед" и проверить будет ли функция с таким именем. Во всех статьях по этой теме, пишут, что предосмотр сканера вперед, должен быть максимум на 1 токен, у Вирта например. В противном случае есть опасность зацикливания или out of memory на некоторых наборах лексем и всякие прочие гадости.
Есть вариант сделать сначала проход по таблице лексем и выбрать все имена функций и занести их в отдельную таблицу, затем сделать проход и выбрать все метки, потом все переменные и т.д. Но это выглядит как-то совсем уж медленно.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Проверка семантики кода

Сообщение Хакер » 12.04.2012 (Чт) 17:34

jangle писал(а):А какой вид эти правила в графе имеют в vb-коде? Это какой-то набор SELECT-CASE`ов?

Каждый сам для себя решает. Но Select Case-ом я бы никогда не делал. Поищи по форуму мои постинге по фразам Dfa, Tkn, Krm.
Если бы я делал на VB, я бы сделал так: узел графа представляет функция. Возвращаемое функцией значение — адрес другой функции. Функции принимают в качестве аргумента некоторый контекст, и вольна делать с ним всё, что угодно. Любые побочные эффекты работы функции — обработка входящих данных, не важно, приводящая к построению новой цепочки, нового дерева, новых таблиц. То есть есть семейство функций, имеющих одинаковый прототип, но делающих разные дела. Каждая такая вызываемая функция что-то делает и возвращает адрес другой функции, которая должна сделать следующий шаг (или NULL, если обработка окончена).

И второй подход: как семейство классов, поддерживающих интерфей IRouter, имеющий метод Router и возвращающий адрес объекта-экземпляра любого из классов, поддерживающих интерфейс IRouter.

jangle писал(а):По идее сканер должен генерировать ошибку, он же не может "заглянуть вперед" и проверить будет ли функция с таким именем.

Это в Си так так. В Си++ уже не так, а уж VB — подавно. Ты так и не понял, что нужно делать всё послойно, а не одним махом. По сути послойный поэтапный подход заменяет необходимость заглядывать вперёд.

И почитай мой пост (поищи в трепе) о том, как устроена VB6 IDE/VBA IDE. Там исходный код, над которым программист работает в IDE, вообще не хранится в памяти IDE. Так вот, VB6 не хранит строку foo = bar(4) как присвоение переменной foo значения, возвращённого функции bar. VB хранит лишь информацию о том, что чему-то (но неизвестно, чему) с именем «foo» происходит присвоение выражения «что-то(4)», причём известно, что «что-то» имеет имя bar, но не известно, функция ли это, или же параметрическое свойство или же массив или переменная.

Сопоставление и проверка «чего-то» с «чем-то» происходит только при нажатии кнопки «Start». И в этот момент уже есть вся информация, необходимая и для проверки и для сопоставления.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

VBTerminator
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 415
Зарегистрирован: 19.11.2008 (Ср) 20:10

Re: Проверка семантики кода

Сообщение VBTerminator » 12.04.2012 (Чт) 18:42

jangle писал(а):Если встречается неизвестная лексема, например имя функции которая встретится значительно позднее в коде, или не встретится. По идее сканер должен генерировать ошибку, он же не может "заглянуть вперед" и проверить будет ли функция с таким именем.

Можно так:
  1. Если компилятор встречает объявление функции, он заносит её имя в таблицу функций.
  2. При встрече с вызовом функции компилятор смотрит, есть ли её имя в таблице:
    • Если есть, то заменяем упоминание функции на её номер в таблице.
    • Если такая функция не объявлялась и ранее не использовалась, добавляем её в таблицу с пометкой "неудовлетворённая зависимость". Затем, здесь и далее подставляем её номер, как у нормальной функции.
    • При дальнейшей встрече с реализацией этой функции компилятор просто снимает с соответствующей ей записи пометку.
  3. После компиляции просматриваем список функций. Если в нём есть экземпляры с вышеуказанной пометкой, повторно проходимся по коду, на этот раз просто заменяя вызовы на номера.
  4. Если и после этого у нас есть функции без реализаций, значит они могут быть объявлены в другом модуле - сохраняем эти записи на потом.

То же самое и для других объявляемых сущностей (переменных, импортов и т. д.)

ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Re: Проверка семантики кода

Сообщение ger_kar » 12.04.2012 (Чт) 19:37

Наверное стоит написать свой компилятор, не ради самого компилятора, а именно что-бы пройти этот путь, после его прохождения в сознании наверное произойдут достаточно большие изменения в лучшую сторону :)
Бороться и искать, найти и перепрятать

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Re: Проверка семантики кода

Сообщение jangle » 12.04.2012 (Чт) 20:59

Хакер писал(а):Каждый сам для себя решает. Но Select Case-ом я бы никогда не делал. Поищи по форуму мои постинге по фразам Dfa, Tkn, Krm.
Если бы я делал на VB, я бы сделал так: узел графа представляет функция. Возвращаемое функцией значение — адрес другой функции. Функции принимают в качестве аргумента некоторый контекст, и вольна делать с ним всё, что угодно. Любые побочные эффекты работы функции — обработка входящих данных, не важно, приводящая к построению новой цепочки, нового дерева, новых таблиц. То есть есть семейство функций, имеющих одинаковый прототип, но делающих разные дела. Каждая такая вызываемая функция что-то делает и возвращает адрес другой функции, которая должна сделать следующий шаг (или NULL, если обработка окончена).


Идея с функциями которые что-то делают, а потом вызывают другие для следующего шага, прикольная. Но тут проблема, что вся семантика языка оказывается размазанной в логике вызова этих функций. И если захочешь изменить что-то в языке, придется переписывать эту логику заново. А хотелось бы, чтобы "правила языка" или графы были сосредоточены в некой таблице, и чтобы изменить язык, достаточно просто исправить только эту таблицу.

VBTerminator писал(а):[*]Если компилятор встречает объявление функции, он заносит её имя в таблицу функций.


В VB это не сработает. Потому что здесь функция может начать использоваться до ее описания. Нет обязательного декларирования прототипов функций, как например в PB или Cи.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Проверка семантики кода

Сообщение Хакер » 12.04.2012 (Чт) 21:37

jangle писал(а):Идея с функциями которые что-то делают, а потом вызывают другие для следующего шага, прикольная.

Функции не вызывают друг-друга. Функции переходят друг-на-друга. Но поскольку goto между функциями невозможен, реализуется это так: одна функция возвращает некоему диспетчеру в качестве возврата адрес следующей функции, а диспетчер вызывает следующую функцию.

jangle писал(а):А хотелось бы, чтобы "правила языка" или графы были сосредоточены в некой таблице, и чтобы изменить язык, достаточно просто исправить только эту таблицу.

Всегда можно маршрутизирующие функции написать универсальным образом, чтобы они руководствовались некоторыми исходными нефиксированными данными для выбора логики работы и логики выбора адрес следующей функции для возврата его (адресу) диспетчеру для последующего вызова. И создать метаязык описания правил построения графов. Хочешь лишний геморрой — делай. Собственно, в своё время я именно так и сделал.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Re: Проверка семантики кода

Сообщение ger_kar » 12.04.2012 (Чт) 22:04

jangle писал(а): Нет обязательного декларирования прототипов функций, как например в PB

Help писал(а):Previous versions of PowerBASIC required that you create an explicit DECLARE statement if you wished to execute a SUB or FUNCTION which did not physically precede the reference to it. This extra work is no longer required, as PowerBASIC resolves all forward references to internal procedures automatically.

DECLARE statements for a Sub/Function imported from a DLL must still precede any reference to the procedure.
Бороться и искать, найти и перепрятать

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Re: Проверка семантики кода

Сообщение jangle » 13.04.2012 (Пт) 10:36

Хакер писал(а):реализуется это так: одна функция возвращает некоему диспетчеру в качестве возврата адрес следующей функции,


Поскольку в VB нет указателей на функции, придется передавать ее имя?

ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Re: Проверка семантики кода

Сообщение ger_kar » 13.04.2012 (Пт) 10:40

jangle писал(а):Поскольку в VB нет указателей на функции, придется передавать ее имя?
А чем не устраивает кирпич с вызовами ф-ций по указателю?
Бороться и искать, найти и перепрятать

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Re: Проверка семантики кода

Сообщение jangle » 13.04.2012 (Пт) 11:42

ger_kar писал(а):
jangle писал(а):Поскольку в VB нет указателей на функции, придется передавать ее имя?
А чем не устраивает кирпич с вызовами ф-ций по указателю?


Там нестандартные приемы используются, нет гарантии что будет работать во всех ситуациях.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Проверка семантики кода

Сообщение Хакер » 14.04.2012 (Сб) 18:38

:|

Если ты не доверяешь одному моему решению, то какой смысл сейчас вести разговор о другом моём решении.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Re: Проверка семантики кода

Сообщение jangle » 14.04.2012 (Сб) 20:46

Хакер писал(а)::|

Если ты не доверяешь одному моему решению, то какой смысл сейчас вести разговор о другом моём решении.


Вполне доверяю, но есть опасения что нестандартные решения могут не работать в некоторых ситуация. Например много указателей, ос 9x или 64bit или что-то подобное

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Проверка семантики кода

Сообщение Хакер » 14.04.2012 (Сб) 21:49

На 64x мы тестировали. На 9x — не тестировали, но какой смысл.
Если работает Declare, то заработают и мои указатели. Кирпич основан просто на перезаписи ячейки с адресом, которую штатно использует declare.

К тому же, если ты не хочешь довериться кирпичу, я же написал: меняем функцию на метод класса. Функция возвращает уже не указатель на функцию, а ссылку на объект некоторого класса, поддерживающего интерфейс IRouter. Зачем было придумывать несусветный пример про возврат имени функции вместо адреса?
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Re: Проверка семантики кода

Сообщение ger_kar » 14.04.2012 (Сб) 21:56

Хакер писал(а):Если работает Declare, то заработают и мои указатели.
А есть какие нибудь ограничения на количество объявленных Declare? Таблица с адресами может переполниться?
Бороться и искать, найти и перепрятать

VBTerminator
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 415
Зарегистрирован: 19.11.2008 (Ср) 20:10

Re: Проверка семантики кода

Сообщение VBTerminator » 15.04.2012 (Вс) 8:36

Хакер писал(а):На 9x — не тестировали, но какой смысл.

Ага, учитывая, что (согласно MSDN) львиная доля API появилось только в Win2000.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Проверка семантики кода

Сообщение Хакер » 15.04.2012 (Вс) 13:45

VBTerminator писал(а):Ага, учитывая, что (согласно MSDN) львиная доля API появилось только в Win2000.

Ну-ну. Люди, которые успели застать 9x, знают, какие там были API. И эти люди заходя в современный MSDN прекрасно понимают, что в нынешнем MSDN в описании API-функция информация по 9x по политическим причинам была удалена вообще. То есть если есть тысяча функций, и все из них были доступны в Windows 95, в нынешнем MSDN будет написано, что минимальная ОС, в которых эти функции появились: это Windows 2000.

CreateWindowEx.

Современный MSDN пишет, что она появилась в Windows 2000!
Кем надо быть, чтобы считать, что в Windows 95 её не было? Как тогда работали все программы под Windows 95? Как они создавали окна?

Нужно просто посмотреть на MSDN Library от Visual Studio 6. Или хотя бы на онлайн MSDN в веб-архиве по состоянию на 2005-ый год:
http://web.archive.org/web/200503181350 ... ndowex.asp

Старый добрый MSDN о CreateWindowEx писал(а):Minimum operating systems Windows 95, Windows NT 3.1


Это к тому, что что
VBTerminator писал(а):львиная доля API появилось только в Win2000.
— бред и дезинформация.

Но даже если бы это утверждение было правдой, неужели ты думаешь, что те жалкие 4 функции, которые используются в кирпче, могли отсутствовать в Win9X?
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Re: Проверка семантики кода

Сообщение jangle » 17.04.2012 (Вт) 16:18

Хочу сделать компилятор Си-подобного языка в VB. Пока удалось привинтить лексический анализатор и сделать какую-то схему приложения, но до сих пор, не могу разобраться как написать синтаксический анализатор. Нужно чтобы он выдавал семантические ошибки в Си-коде. Если кто-то разбирается в этой теме, приведите хоть один пример. Исходник в аттаче, можно на базе его.
Вложения
Compiler.zip
Компилятор
(7.49 Кб) Скачиваний: 69

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Проверка семантики кода

Сообщение Хакер » 17.04.2012 (Вт) 17:20

Фигня — на уровне подхода.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Re: Проверка семантики кода

Сообщение jangle » 17.04.2012 (Вт) 19:44

Почему фигня? И чем плох подход в исходнике?

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Проверка семантики кода

Сообщение Хакер » 17.04.2012 (Вт) 20:08

Ну, если проводить аналогию. Вот есть же эвалиаторы мат. выражений, несколько даже лежит на форуме. Самый годный, насколько я помню, Тёмычевский.

А теперь представь, что кто-то пишет эвалиятор, и делает его так:
Решает, для начала сделать поддержку выражений вида X+Y и X-Y, а потом уж как-нибудь доделать поддержку более сложных выражений и добавить другие мат. действия.

И пишет его так:
Код: Выделить всё
Function Evaluate(byval expr as string)
    if expr like "*+*" then
        delim="+"
    elseif expr like "*-*" then
       delim = "-"
    else
        error 5
    endif

    parts = split(expr, delim)
    a = parts(0): b = parts(1)
    a = trim(a): b = trim(b)
    a = val(a): b = val(b)

    evaluate = iif(delim = "+", a + b, a - b)
End Function


Вот насколько отличается такой эвалюатор от нормального, настолько же отличает твой код от кода нормального компилятора.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Re: Проверка семантики кода

Сообщение jangle » 17.04.2012 (Вт) 20:43

Вот насколько отличается такой эвалюатор от нормального, настолько же отличает твой код от кода нормального компилятора.


Это еще не компилятор, если конечно смотрел код. Кроме лексического анализатора там собственно ничего и нет.
Код парсит исходник в специальную таблицу лексем, где сохраняется полная информация о каждом токене. Его класс, айдишник класса, номер строки, номер позиции в строке, имя файла откуда взята лексема, область видимости в данный момент. Таблица лексем является тем источником, с которым будет работать уже сам компилятор, отсюда он будет брать информацию о положении лексем в коде для заполнения таблицы ошибок. Столбец Symbol это уже в некотором роде внутреннее представление программы, только надо описать все классы лексем для конкретного языка.
Синтаксический анализатор будет читать инфу из LexTable(i).CLASS выбирая классы лексем и выполняя свертку выражений. Вот как он будет работать я пока понять не могу

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Проверка семантики кода

Сообщение Хакер » 17.04.2012 (Вт) 20:46

Вот та часть, которая уже сделана, отличается от того, как она должна быть сделана, таким же образом, как код постом выше отличается от нормального эвалиятора.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Re: Проверка семантики кода

Сообщение jangle » 18.04.2012 (Ср) 15:07

Здесь не эвалютор, поэтому и код другой. Ничего вычислять не нужно. Подход правильный хотя бы потому, что он формирует корректную таблицу лексем пригодную для дальнейшей обработки.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Проверка семантики кода

Сообщение Хакер » 18.04.2012 (Ср) 17:35

jangle писал(а):Здесь не эвалютор, поэтому и код другой.

jangle, ты издеваешься? Здесь была аналогия. Понимаешь, что такое аналогия? Я мог привести не эвалиатор, а калькулятор, тетрис, графический редактор в качестве примера. Потому что демонстрировалась ошибка в подходе, и выбор примера абсолютно не важен. Я просто выбрал то, что ты гарантированно видел и знаешь.

jangle писал(а):Подход правильный хотя бы потому, что он формирует корректную таблицу лексем пригодную для дальнейшей обработки.

Вот это забавно. Ты просишь помощи: помогите, я не знаю, как делать, расскажите как правильно. Но в процессе огрызваешься: идите нафиг, у меня всё зашибись, не учите меня жить! Я вижу два варианта развития разговора в подобных топиках: либо вопрошающий молча слушает и впитывает, либо он начинает вступать в спор по каждому данному ему указанию на ошибку, но тогда кому он нужен со своей проблемой?
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Re: Проверка семантики кода

Сообщение jangle » 19.04.2012 (Чт) 15:50

Удалось понять как проверяется правильность расстановок скобок любого типа.

Проверка семантики выражений со скобками. Алгоритм

Для проверки корректности скобочных выражений применяется алгоритм синтаксического анализа, основанный на использовании стека. Входное алгебраическое выражение сканируется посимвольно слева - направо, пока не обнаружен признак его конца (EOL, EOP) или ошибка расстановки скобок по правилам указанным ниже. При этом в анализируемом выражении рассматриваются только скобки () [] {} . При обнаружении открывающей скобки любого типа она загружается в стек. При обнаружении закрывающей скобки любого типа анализируется содержание стека. Если стек пуст, то считается, что скобки в выражении расставлены неправильно. Если стек не пуст, то из него выталкивается последняя открывающая скобка и проверяется соответствие, ее типа типу обнаруженной закрывающей скобки () [] {} . Если в рассматриваемой паре скобок открывающая и закрывающая скобки имеют различный тип, выражение считается некорректным, в противном случае, когда скобки из стека и выражения имеют одинаковый тип, продолжается поиск следующей скобки во входном алгебраическом выражении. При достижении признака конца алгебраического выражения вновь анализируется состояние стека. Пустой стек соответствует правильной расстановке скобок. Наличие скобок в стеке соответствует ошибке расстановки скобок.

Пример проверки скобок в аттаче, чтобы вызвать ошибку, нужно удалить или добавить скобки любого типа. Парсер укажет место ошибки.
Вложения
Source Lexer.zip
Парсер
(8.13 Кб) Скачиваний: 72

ger_kar
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1957
Зарегистрирован: 19.05.2011 (Чт) 19:23
Откуда: Кыргызстан, Иссык-Куль, г. Каракол

Re: Проверка семантики кода

Сообщение ger_kar » 19.04.2012 (Чт) 16:07

jangle писал(а):Если стек пуст, то считается, что скобки в выражении расставлены неправильно
jangle писал(а): Пустой стек соответствует правильной расстановке скобок
jangle писал(а):Наличие скобок в стеке соответствует ошибке расстановки скобок
Ты не находишь противоречий в тексте?

x=(sin(1)+2)*var[(1]; В выражении всего 21 символ, включая заключительные точку с запятой.
Syntax Error: Line 1 Position:23 в выражении позиции 23 вообще нет.
Бороться и искать, найти и перепрятать

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Re: Проверка семантики кода

Сообщение jangle » 19.04.2012 (Чт) 16:46

ger_kar писал(а):Ты не находишь противоречий в тексте?


Я разве описал алгоритм приведенным тобой способом?
Хотя допускаю что описано мало понятно, возможно кодом будет лучше пониматься:

Код: Выделить всё
Private Sub Skobki()
Dim i As Long

StackInit
For i = 1 To UBound(LexTable)

   Select Case LexTable(i).ID_CLASS
   
    Case LPARM
      StackPush LPARM
    Case RPARM
       If StackPop <> LPARM Then
          If StackIsEmpty = True Then GoTo ER
          GoTo ER
       End If
   
    Case LCurly
      StackPush LCurly
    Case RCurly
         If StackPop <> LCurly Then
            If StackIsEmpty = True Then GoTo ER
            GoTo ER
         End If
     
   
    Case LBracket
      StackPush LBracket
    Case RBracket
       If StackPop <> LBracket Then
           If StackIsEmpty = True Then GoTo ER
            GoTo ER
         End If
     
    Case EOL, EOP
           If StackIsEmpty = False Then GoTo ER
   End Select
Next i
Me.TextOut = "Нет ошибок со скобками"
Exit Sub
ER:
  Me.TextOut = "Syntax Error: Line " & LexTable(i).STRING_NUMBER & "  Position:" & LexTable(i).LOCAL_STRING_POS
End Sub


в выражении позиции 23 вообще нет.


Разумеется нет, эта позиция есть в таблице лексического анализатора, под которой лежит EOL, лексема на которой алгоритм заканчивает свою работу и выводит сообщение об ошибке. Чтобы он указывал на последнюю незакрытую скобку, нужно просто добавить соответствующий код.

След.

Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: AhrefsBot, SemrushBot и гости: 4

    TopList