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

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

Восстановить пароль Регистрация
Другие темы раздела
C++ Меню и список http://www.cyberforum.ru/cpp-beginners/thread41194.html
Здравствуйте форумчане. Помоги пожалуйста в следующем вопросе: У меня есть 2связный список, написано меню. Но в моменте когда написано make a list и delete custom необходимо чтобы выводились: Введите элемент и номер. вот сам код: #ifndef __list_h #define __list_h #include <iostream>
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!!! Вот текст программы, которая выводит на экран набор треугольников и квадратов, которые произвольно двигаются и меняют размер только квадратов. Проблема в том, что необходимо исправить код, чтоб фигуры не исчезали за экран (т.е. 640х460) и были компактным набором, т.е. двигались неменяя своего положения относительно друг друга и стукаясь об стенку экрана меняли свое...
C++ Округление дробного числа до целого в большую сторону. http://www.cyberforum.ru/cpp-beginners/thread41139.html
Доброго дня. Я новичок в программирование на Visual C++. Проблема такая программа должна считать кол-во месяцев, если числа целые то программа шла дальше, если дробное то (например 3.33333) программа не округляет это число (в большую сторону) до 4. Перелопатил тонны литературы, но пропустил или не нашёл этого, большая просьба написать функцию которая могла бы это делать, или способ какой.
C++ Код из Delphi в C++ Нужно написать курсовую на C++. Сам я в программировании плохо шарю (не программист). Попросил у народу помощи, помогли. Но решение на Delphi: {$APPTYPE CONSOLE} type byteset=set of byte; var d:array of longint; procedure c; var a,b,i:longint; подробнее

Показать сообщение отдельно
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
26.11.2011, 13:36     Пишем свой интерпретатор языка BASIC
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. Т.е. целевой символ получатся только единожды, в конце разбора. Если парсер не смог дойти до него, или же после того, как он его получил, лексер продолжает возвращать лексемы, то это свидетельствует об ошибке.
 
Текущее время: 13:13. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru