Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

Пишем свой интерпретатор языка BASIC - C++

Войти
Регистрация
Восстановить пароль
Другие темы раздела
C++ Меню и список http://www.cyberforum.ru/cpp-beginners/thread41194.html
Здравствуйте форумчане. Помоги пожалуйста в следующем вопросе: У меня есть 2связный список, написано меню. Но в моменте когда написано make a list и delete custom необходимо чтобы выводились:...
C++ Здравствуйте! Не могу поместить class в один файл с программой. file.hpp #include "Cat.hpp" // здесь классы "2)" Cat::Cat(int initialAge) { itsAge = initialAge; } Cat::~Cat() { http://www.cyberforum.ru/cpp-beginners/thread41186.html
Массивы строк C++
Привет всем! Задан массив строк. Как узнать который символ встечаетса найбольшое количество раз в етом массиве?
C++ вывод на экран набор треугольников и квадратов, которые произвольно двигаются и меняют размер
Please, help me!!! Вот текст программы, которая выводит на экран набор треугольников и квадратов, которые произвольно двигаются и меняют размер только квадратов. Проблема в том, что необходимо...
C++ Округление дробного числа до целого в большую сторону. http://www.cyberforum.ru/cpp-beginners/thread41139.html
Доброго дня. Я новичок в программирование на Visual C++. Проблема такая программа должна считать кол-во месяцев, если числа целые то программа шла дальше, если дробное то (например 3.33333) ...
C++ Код из Delphi в C++ Нужно написать курсовую на C++. Сам я в программировании плохо шарю (не программист). Попросил у народу помощи, помогли. Но решение на Delphi: {$APPTYPE CONSOLE} type byteset=set of byte; ... подробнее

Показать сообщение отдельно
silent_1991
Эксперт С++
4984 / 3041 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
26.11.2011, 13:36
taras atavin, первое предложение языка, задающегося данной грамматикой, а не statement - да, должно начинаться с начала файла, разумеется. Но к целевому символу это имеет мало отношения. Суть целевого символа в том, что анализатор в конечном итоге сможет свернуть корректную программу на языке, задаваемом грамматикой, к целевому символу proram. Потому он и называется целевым, что цель парсера - прийти к нему и только к нему одному в результате свёрток по правилам грамматики.

Добавлено через 1 час 21 минуту
Возьмём грамматику, предложенную Nameless One. Я дополню её, чтобы она была законченной:
Код
program -> definitions
definitions -> definitions definition | 'EPS'
definition -> prototype body
prototype -> typespec qualifier '(' paramlist ')'
paramlist -> param | paramlist ',' param | 'EPS'
param -> typespec qualifier
body -> '{' statements '}'
statements -> statement ';' | statements statement ';' | 'EPS'
typespec -> 'int' # Пусть в качестве типа выступает int и только он (для простоты)
statement -> 'return 0' # Предложением будет мифический терминал 'return 0' (также для простоты)
qualifier -> letters # Я немного изменил грамматику для простоты, теперь как funid, так и varid являются qualifier, который, в свою очередь - набор строчных букв латиницы (как минимум одна буква)
letters -> letter letters | letter 'EPS'
letter -> 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z'
Также для наглядности я позволил себе внести левую рекурсивность в грамматику. При построении парсера от неё надо избавляться (для этого существует простой алгоритм).

Рассмотрим теперь простую программу на данном языке, состоящую из одной функции:
Код
int a(int b)
{
    return 0;
}
Для начала опишу упрощённую схему работы связки лексический анализатор-синтаксический анализатор. Лексический анализатор возвращает синтаксическому лексемы. Синтаксический (обычно реализуемый при помощи конечного автомата со стековой памятью, хотя есть и другий способы) заталкивает эту лексему в стек (т.н. сдвиг). В стеке хранятся как терминалы, так и нетерминалы (как они там появляются - далее). Если в стеке оказался набор символов (терминальных или нетерминальных), соответствующий какому-то правилу грамматики, эти символы удаляются из стека, а их место занимает нетерминал, порождающий удалённый набор символов. Так в стеке (на начальном этапе содержащем только лексемы) появляются нетерминалы.
А теперь заделаемся парсером и выполним его действия (примерно, лишь для пояснения):
Изначально стек пуст. Лексический анализатор вернул синтаксическому лексему 'int'. Произошёл сдвиг. В стеке
Код
'int'
Для данного терминала существует порождающее правило typespec -> 'int'. Поэтому происходит свёртка по этому правилу. В стеке
Код
typespec
Далее вернулась лексема a'. В стеке
Код
typespec 'a'
Терминал 'a' сворачивается к нетерминалу letter. Происходит свёртка. В стеке
Код
typespec letter
letter, в свою очередь, сворачивается к letters по правилу letters -> letter 'EPS'. Ну а letters сворачивается к qualifier (я объединил две свёртки для наглядности). В стеке
Код
typespec qualifier
Возвращается '('. В стеке
Код
typespec qualifier '('
Затем возвращается 'int', который можно свернуть к typespec. В стеке
Код
typespec qualifier '(' typespec
Возвращается 'b', который снова проводим через цепочку letter -> letters -> qualifier. В стеке
Код
typespec qualifier '(' typespec qualifier
Последовательность typespec qualifier можно свернуть к param, а его сразу можно свернуть к paramlist. В стеке
Код
typespec qualifier '(' paramlist
Возвращается ')' В стеке
Код
typespec qualifier '(' paramlist ')'
Данный набор символов можно свернуть к prototype, что и делает парсер. В стеке
Код
prototype
Возвращается '{', 'return 0', ';', '}'. 'return 0' и ';' можно свернуть к statement, а его с statements. Последовательность '{', statements, '}' сворачивается к body. В стеке
Код
prototype body
Это можно свернуть к definition, а его, в свою очередь, к definitions. В стеке
Код
definitions
Программа завершилась, поэтому definitions можно свернуть к program, к целевому символу. Целевой символ получается только если программа полностью разобрана и она корректна (т.е. удовлетворяет языку, определяемому грамматикой, по которой строился парсер).
Будь в программе две функции, после разбора первой в стеке оказалось бы
Код
definitions
, после разбора второй
Код
definitions definition
Который также свернулся бы к definitions, а только этот definitions в итоге свернулся бы к program. Т.е. целевой символ получатся только единожды, в конце разбора. Если парсер не смог дойти до него, или же после того, как он его получил, лексер продолжает возвращать лексемы, то это свидетельствует об ошибке.
4
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru