Временно недоступен
957 / 228 / 14
Регистрация: 12.04.2009
Сообщений: 926
|
||||||||||||||||||||||||||||||||||||||||||||||
1 | ||||||||||||||||||||||||||||||||||||||||||||||
Пишем свой интерпретатор языка BASIC20.06.2009, 20:03. Показов 242552. Ответов 464
Метки нет (Все метки)
Благодаря форуму и Evg в частности интерпретатор развивается, потихоньку превращаясь в простенький интерпретатор QBASIC.
Некоторые из самых старых версий сохранились в теме и ссылки на них будут добавлены в это сообщение,а также ссылки на другие темы,связанные с этой. Репозиторий с проектом находится тут, там же есть возможность в браузере посмотреть историю ревизий (английский в логах весьма примитивен,комментарии и рекомендации можете писать в личку),а также скачать самый последний архив репозитория в формате .tar.gz Если кто-то пользуется Subversion,скачать исходники можно так: Код
svn co https://basin.svn.sourceforge.net/svnroot/basin basin Технический приём для формирования согласованных данных https://www.cyberforum.ru/c-linux/thread46096.html Вопрос по svn (Subversion) Создание системы тестирования ПО. Вопрос про разные реализации бэйсиков Можно ли выразить порядковый номер элемента массива через индексы? [C++] Какие флаги указать линкеру для компиляции программы? Как можно определить переменную в файле configure.in,чтобы её можно было использовать в Makefile? Странный SIGSEGV, или что зависит от порядка написания интерфейса класса https://www.cyberforum.ru/c-linux/thread61324.html Альтернативная версия интерпретатора от Evg на C Это простая реализация разбора выражений, написанная Evg на C: Представление выражения в двоичном дереве ***************** Первое сообщение: ***************** Задание(Страуструп,из книги,по готовому коду): Введите программу калькулятора и заставьте её работать.Например,при вводе
LexicalAnalyzer.h
LexicalAnalyzer.cpp
main.cpp
Анализатор-то работает,но конечное значение не вычисляется.Более того,если вводим
Добавлено через 2 часа 5 минут 30 секунд Пришлось решать влоб с дебаггером.У Страуструпа опечатка (или намеренная ошибка,что более вероятно ) Вот в этом куске кода в функции get_token():
Добавлено через 16 минут 19 секунд И ещё опечатка была
31
|
20.06.2009, 20:03 | |
Ответы с готовыми решениями:
464
Пишем свой интерпретатор языка BASIC Пишем свой strlen Пишем свой чекер пишем свой троян с нуля |
16.09.2009, 16:33 | 121 |
Насколько я понял, в момент интерпретации IF'а для одной из его веток ты вызываешь interp_Run.
Доходишь до метки. Далее делаешь переход на метку. Опять попадаешь в interp_stmtIF. В итоге получается бесконечная рекурсия Добавлено через 12 минут Ну и вообще я так с ходу не совсем пойму, как GOTO внутри IF'а отработает. По логике вещей при окончании списка мы должны вернуться из процедуры interp_Run Код
LET B1 = 5 IF B1 THEN GOTO 2 PRINT B1+1 2: PRINT B1+2
1
|
Временно недоступен
957 / 228 / 14
Регистрация: 12.04.2009
Сообщений: 926
|
|
16.09.2009, 17:29 [ТС] | 122 |
Только вот как? GOTO же требует,чтобы выполнялся оператор за меткой,так вроде логично что это уже на плечах программиста .Как можно вернуться из инструкции,если управление передаётся опять на IF?Что-то не пойму .
А,я понял что ты имел ввиду походу выход там есть просто в interp_Run когда вызывается из IF -а подставляется ЛОКАЛЬНЫЙ список statement-ов,а statement из THEN всего один(только GOTO в нашем случае),и после этого происходит возврат из IF.Ну вроде так
0
|
16.09.2009, 17:32 | 123 |
Я просто не могу чётко сформулировать свою мысль, т.к. в деталях не знаю, как у тебя работает. Попробуй для начала вышеобозначенные ошибки исправить, может самому станет понятно
1
|
Временно недоступен
957 / 228 / 14
Регистрация: 12.04.2009
Сообщений: 926
|
|
16.09.2009, 19:28 [ТС] | 124 |
Я кажись понял я ту ошибку исправил,но и правда с GOTO ошибка есть.Происходит это потому,что GOTO меняет значение счётчика,но это работает только для списка инструкций,по которому идёт интерпретация.Поэтому с IF получается,что происходит попытка проинтерпретировать инструкцию в списке,которой там нет(так как у THEN только одна инструкция,а именно GOTO).Отсюда и ошибка.
Я вот думаю,как можно это поправить "малой кровью" =) Может,сделать чтобы все интерпретирующие функции возвращали порядковые номера в глобальном списке,по умолчанию свои,а если идёт передача управления(как у GOTO),то номер инструкции в списке,которая должна интерпретироваться следующей.. В-общем у меня ощущение,что в целом направление правильное(отдельные списки для WHILE и IF,проверка синтаксиса в них),но я не уверен.
0
|
16.09.2009, 20:14 | 125 |
Тут беда не только в том, что нет номера в списке, а ещё и в том, то у тебя возникает рекурсия. Т.е. после GOTO ты по сути дела начинаешь по новой интерпретировать самый верхний список операторов (поскольку метка в начале программы). Но этот список ты уже интерпретируешь внутри второй активации RunList - т.е. когда ты попадаешь в операцию присваивания и в этом месте смотришь стек интерпретатора, то получается, что с каждым попадением в эту точку стек у тебя растёт. Либо я как-то не так представляю, как у тебя работает, но на первый взгляд получается именно так
1
|
105 / 104 / 9
Регистрация: 12.09.2009
Сообщений: 452
|
|
16.09.2009, 21:07 | 126 |
0
|
Временно недоступен
957 / 228 / 14
Регистрация: 12.04.2009
Сообщений: 926
|
|
16.09.2009, 22:37 [ТС] | 127 |
Книга называется "Язык программирования С++" Б.Страуструп.Специальное издание.
Но по сути,исходники программы,получившейся в итоге,довольно далеки от книжной версии.
1
|
105 / 104 / 9
Регистрация: 12.09.2009
Сообщений: 452
|
|
16.09.2009, 22:46 | 128 |
На сколько далеки???
0
|
Временно недоступен
957 / 228 / 14
Регистрация: 12.04.2009
Сообщений: 926
|
|
16.09.2009, 22:55 [ТС] | 129 |
Ну возьми книгу и сравни с исходниками последней версии тут http://basin.svn.sourceforge.net/
По сути-это совешенно другая программа,и общего между ними - только то,что способ рекурсивного спуска при разборе выражений - тот же.
0
|
105 / 104 / 9
Регистрация: 12.09.2009
Сообщений: 452
|
|
16.09.2009, 23:12 | 130 |
Ага, спасибо...
Добавлено через 15 минут А о такой книге слышал что нибудь ?? Харви Дейтл, Пол Дейтл "Как програмировать на C++" Говорят что хорошая...
1
|
Временно недоступен
957 / 228 / 14
Регистрация: 12.04.2009
Сообщений: 926
|
|
17.09.2009, 00:40 [ТС] | 131 |
Я слышал плохое ...
Я попытаюсь понять как это исправить ... Но в общем я вижу это не как рекурсию,но склонен доверять тебе,постараюсь понять..
0
|
17.09.2009, 08:10 | 132 |
Давай тогда добейся того, чтобы для начала эти примеры заработали, а там видно будет. Просто это одно из моих предположений, которое я надумал, пока тебе объяснял принцип построения промежуточного представления
1
|
17.09.2009, 18:36 | 134 |
У меня gcc-4.2.1
Ревизия 21 ломается на компиляции (линковке) Код
syntax.o: In function `syntax_IdentRValue()': syntax.cpp:(.text+0x309f): undefined reference to `defined_arrays' syntax.cpp:(.text+0x30aa): undefined reference to `FindNameOverVector(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::vector<Array*, std::allocator<Array*> >&)' syntax.o: In function `syntax_StmtLET(std::vector<Statement*, std::allocator<Statement*> >*)': syntax.cpp:(.text+0x387c): undefined reference to `defined_arrays' syntax.cpp:(.text+0x3887): undefined reference to `FindNameOverVector(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::vector<Array*, std::allocator<Array*> >&)' syntax.o: In function `syntax_stmtDIM(std::vector<Statement*, std::allocator<Statement*> >*)': syntax.cpp:(.text+0x3f0d): undefined reference to `defined_arrays' syntax.cpp:(.text+0x3f18): undefined reference to `FindNameOverVector(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::vector<Array*, std::allocator<Array*> >&)' syntax.cpp:(.text+0x4159): undefined reference to `Array::Array(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, Types)' syntax.cpp:(.text+0x42e7): undefined reference to `defined_arrays' interp.o: In function `interp_stmtDIM(Statement const*)': interp.cpp:(.text+0x33c0): undefined reference to `defined_arrays' interp.cpp:(.text+0x33cb): undefined reference to `FindNameOverVector(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::vector<Array*, std::allocator<Array*> >&)' interp.cpp:(.text+0x344e): undefined reference to `defined_arrays' interp.cpp:(.text+0x3461): undefined reference to `Array::SetDimensions(std::vector<unsigned long, std::allocator<unsigned long> >*)' interp.cpp:(.text+0x346f): undefined reference to `defined_arrays' interp.cpp:(.text+0x347e): undefined reference to `Array::ArrZeroInit()' interp.cpp:(.text+0x348c): undefined reference to `defined_arrays'
1
|
Временно недоступен
957 / 228 / 14
Регистрация: 12.04.2009
Сообщений: 926
|
||||||
18.09.2009, 16:54 [ТС] | 136 | |||||
Я первый раз слышу про такой символ.Что за символ и как пропускать?
UPD.А всё я прочитал надо просто в парсере добавить его.Просто интересно почему у тебя ломается,а у меня работало ... Насчёт GOTO я подумал,что всё таки лучше будет наверное работать по схеме,когда при интерпретации функция возвращает указатель на следующую инструкцию,я вот только не знаю как это сделать с IF THEN ELSE,в случае если есть ветка ELSE и нужно в конце ветки THEN указать,какой оператор следующий,как это определить на этапе синтаксиса.Что-то у меня каша в голове постоянно Или может завести какую-то глобальную переменную,показывающую номер текущей инструкции,чтобы проверялась каждый раз при интерпретации,и если есть GOTO,то в эту переменную пишется номер нужной инструкции в списке?Я сегодня точно посмотрю,как точно должна отрабатывать схема
Добавлено через 19 минут Как вообще туда попал этот символ '\r',вот что интересно..
0
|
18.09.2009, 17:10 | 137 |
Ну просто у всех нормальных людей энетр кодируется одним символом "\n". А в DOS/Windows - двумя "\n\r" (или в обратном порядке, точно не помню). При открытии файла в текстовом режиме fopen (<name>, "r") эта пара символов на уровне системной библиотеки возвращается как один символ "\n", при записи в файл (и печати), соотвественно, наоборот. При окрытии файла в бинарном виде (т.е. в fopen подаётся "rb" вместо "r") такого читерства не делается. Как это в Си++ поддерживается - хз. Как этот символ попал в файл - скорее всего что-то правил под виндами
> Насчёт GOTO я подумал,что всё таки лучше будет наверное работать по схеме,когда при интерпретации функция возвращает указатель на следующую инструкцию Я так и делал - см. процедуру interp_InterpStatementBRANCH и место её вызова > я вот только не знаю как это сделать с IF THEN ELSE А потому я с этой помойкой и не заморачивался. Ввёл три операции управления: метка, условный переход и безусловный переход. И все языковые операторы управления (IF, WHILE, FOR) реализовал через эти три операции промежуточного представления - см. syntax_StatementIF. Если имеешь хоть какое-то понятие о том, как работает процессор на уровне системы команд или зоть как-то писал программы на ассемблере, то поймёшь, что здесь точно такая же логика - вся программа выстроена в виде цепочки операций, некоторые из которых являются операциями перехода (условного или безусловного)
1
|
Временно недоступен
957 / 228 / 14
Регистрация: 12.04.2009
Сообщений: 926
|
|||||||||||
18.09.2009, 17:29 [ТС] | 138 | ||||||||||
Как этот символ правильно пропускать и,может,есть ещё какие-то поводные камни в этом направлении?Всякие там управляющие символы,последовательности и прочее?Что-то у меня не выходит,поскольку в потоке нет перевода строки,как то так получается,что слово PRINT в этом исходнике
И в том то и дело,что я под виндами вообще не сижу .. вот и не знаю,как и когда \r туда мог попасть Добавлено через 15 минут Я нашел как поправить.. но вопрос про всякие левые символы в силе.
0
|
18.09.2009, 17:45 | 139 | |||||||||||||||||||||||||
Мой интерпретатор метки пока не поддерживает, но они неявно появляются в if'е. Грубо говоря, когда ты в структурном виде пишешь программу
Т.е. если для моей версии написать исходник
Код
s1. LET A = 5 s5. CBRANCH (A < 6) -> t=s2(#then), f=s3(#else) <-- переход по true на операцию s2, по false на s3 s2. LABEL #then <--- аналог метки L1 s6. LET A = 1 s7. LET B = 2 s8. BRANCH -> s4(#finish) <---- безусловный переход на операцию s4 s3. LABEL #else <--- аналог метки L2 s9. LET A = 100 s10. LET B = 200 s4. LABEL #finish <--- аналог метки L3
Добавлено через 6 минут Теоретически я мог под виндами что-то подправить в своём исходнике и выложить на форум, а ты уже скопировал оттуда Сложно сказать. Я просто на все неизвестные символы выругиваюсь и всё. У меня есть вызов isspace, который проверяет на всякие пробельные символы, туда входит табуляция и возможно ещё что-то, что меня мало заботит, т.к. интефейс для того и писали, чтобы не разбираться в этом (\r туда возможно тоже попал). Файл я открываю как "rb", а потому с энтером он схлопнуться не должен
1
|
22.09.2009, 22:48 | 140 | |||||
Появилось немного времени, сделал у себя поддержку меток и GOTO. Писал для своей реализации хитрожопый тест. Попробовал на твоей версии (с адаптацией под твой синтаксис) - заработало. Можешь тест добавить к себе в набор (не пропадать же ему)
И твоя и моя версия страдают недостатком выдачи диагностики - временами без поллитры не разберёшь, что оно хочет. Современные умные компиляторы позволяют более точно жиагностировать ошибку - они указывают не только номер файла и строки, но ещё и номер позиции в строке. Понятное дело, что сейчас это вообще не критично, но это ещё одна вещь, которая нужна для хорошего программного продукта - нормальный диалог с пользователем. Просто для порядка имей в виду Я так понимаю, что тестовый пример в репозитории отражает все поддерживаемые конструкции? Добавлено через 2 минуты Смотрю ты концепцию условных переходов переделал. Ты просто содрал или всё-таки разобрался, чем плох старый вариант? Добавлено через 11 минут В общем больше не получилось подобрать примеры, чтобы интерпретатор ломался или работал неправильно. В исходниках копаться уже совсем тяжело, так что пока прими поздравления: то, что уже есть, с виду работает так как надо
1
|
22.09.2009, 22:48 | |
22.09.2009, 22:48 | |
Помогаю со студенческими работами здесь
140
Пишем свой класс, спецификатор доступа protected Интерпретатор небольшого языка программирования на С++ Не удается откомпилировать интерпретатор М-языка Интерпретатор музыки стандарта BASIC PLAY на С++ Написать интерпретатор программного языка -помощь Интерпретатор/компилятор ассемблер-подобного языка Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |