Форум программистов, компьютерный форум 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; подробнее

Показать сообщение отдельно
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16824 / 5245 / 319
Регистрация: 30.03.2009
Сообщений: 14,121
Записей в блоге: 26
04.08.2009, 17:44     Пишем свой интерпретатор языка BASIC
Сам понимаешь, после отпуска с ходу сложно что-то сделать полезное для человечество. Некоторое время должно пройти в традиционно российском виде спорта - борьбе с ленью

По поводу ошибок, грязности кода и прочее - это совершенно нормальное явление. Тем более для тебя, как для начинающего. После того, как интерпретатор придёт в более-менее устаканившееся состояние, в любом случае нужно будет выделить время и заняться генеральной чисткой мусора. Потому как без этого дальнейшее развитие будет затруднённым

По поводу неявного приведения типа. Приведение к более широкому типу - я в первый раз такое слышу. По стандарту, как мне казалось, всегда второй операнд приводится к типу первого. Т.е. int+double эквивалентно "int+(int)double". Но на всякий случай уточню

Про GOTO я не зря разговор затеял. Потому как "хорошее" решение повлечёт за собой серьёзную переделку программы. Принцип останется тот же, но начинка немного поменяется. При этом ситуация "рабочая". Т.е. в реальной жизни с реальными коммерческими продуктами с похожей ситуацией сталкиваются часто

Как у тебя реализованы IF'ы? То, что ты ввёл FI, даёт мне повод заподозрить, что одну из альтернатив ты просто пропускаешь без разбора. А потому, если в пропущенной альтернативе есть синтаксическая ошибка, то ты её в этот момент не поймаешь. А поймаешь только тогда, когда исполнение пойдёт по этой альтернативе. Сие означает, что твоя программа, содержащая синтаксическую ошибку, может довольно долго работать (к примеру, несколько дней), но потом сломаться из-за досадной опечатки. Понятно, что для тренировочной программы это мелочь, но вообще проблема серьёзная.

Добавлено через 6 минут 49 секунд
Цитата Сообщение от qwert Посмотреть сообщение
А как называется книга из которой этот пример? Судя по коду она не для начинающих.
Попробую немного более расширенно ответить.

Изначально #pragma делал просто задачу из книги, в которой простенький разбор выражений с печатью результата. В одной из других тем, я спросил его, насколько серьёзно он собирается заниматься программированием. Он ответил, что серьёзно. А потому данную задачу я предложил ему "чуть-чуть" расширить, а потом это "чуть-чуть" вылилось в довольно серьёзную задачу.

В книжках этого ты нигде не найдёшь (разве что готовое решение с краткими пояснениями). Ну и большая практическая польза была в том, что pragma в данном случае прошёл по пути, когда делается неправильное решение, потом переделывается на более правильное. При этом весь процесс работы он ведёт самостоятельно, я лишь делаю небольшие теоретические выкладки (которых тоже, к сожалению, в книжке скорее всего не встретишь). К тому же параллельно зацепляется очень много моментов по технике программирования: задача из нескольких модуле, правильная организация структур данных да и просто программирование на Си++. Всё это делается "под конкретного человека", потому как многие идеи и технические решения pragm'ы остаются за кадром. С моей стороны вся теоретическая часть в теме присутсвует. Так что если есть интерес, попробуй прочти всю тему с начала и повторить всё это безобразие на практике

Добавлено через 1 час 52 минуты 30 секунд
На текущий момент мне видится следующий порядок действий (именно в таком порядке):
  1. Учимся работать с svn. Если ты ещё не перешёл на хранение исходников под управлением svn.
  2. Делаем тестовый пакет с автоматическим запуском и проверкой. Ты уже успел заметить, что после некоторых твоих правок у тебя протухла работа ELSE. Чтобы такого не происходило в дальнейшем, нужно ставить на контроль функциональность твоего интепретатора. Если пояснить на пальцах, то, например, имеем несколько тестовых исходников на бейсике, в которых делается некая контрольная печать, по которой можно сделать вывод о правильной работоспособности той или иной конструкции. Есть эталонная печать. Тестирование заключается в запуске всех тестов и сравнении выдачи с эталонной. Догадываюсь, что этим заниматься лениво, особенно сейчас, но без этого ты не сможешь удерживать стабильность работы интерпретатора
  3. Обсуждаем дальнейшую внутреннюю структуру интерпретатора. Сейчас у тебя наконец появилось общее понимание того, как работает интерпретатор, а потому уже можно приступать к обсуждению. Проблема сам понимаешь какая: построение работы таким образом, чтобы наиболее просто работать с НЕпоследовательной интерпретацией
  4. Реализация базы интерпретатора. Т.е. строим все управляющие конструкции: IF, FOR, GOTO, WHILE, функции. После чего нужно окинуть критическим взглядом реализованное и начать наводить порядок. Потому как дальнейшее развитие поддержки языка будет, в основном, лишь в части добавления новых операторов, базовая часть при этом, скорее всего, останется в неизменном виде (если опять не возникнет желания навести порядок). В том числе будем разбираться и с динамической памятью (в чём заключается проблема, я пока не понял)

Более далёкая перспектива
  1. Допиливание конструкций, внимательное изучение языка (бейсика) с целью привести наш интерпретатор как можно ближе к стандартным бэйсикам. В том числе и можно решать, как у нас быдет язык чувствовать регистр букв (т.е. "IF" и "if" будет одно и тоже или нет и т.п.)
  2. Перенос интерпретатора на другую платформу (например, windows). Итоговое написание интерпретатора в виде кросс-платформенной программы. Идеальным вариантом будет поддержка в интерпретаторе графики: под виндой и линухом это строится на совершенно разных принципах
  3. Реализация IDE для интерпретатора (по типу всяких билдеров)
  4. Реализация отладчика. ХЗ, есть ли отладчики у интерпретаторов, но в теории вроде бы это ничему не противоречит. Если делать только под текстовый режим, то 100% это реализуемо и не особенно сложно

Добавлено через 6 часов 58 минут 9 секунд
отом могу забыть. Ещё в линуксовом разделе заведи отдельную тему по Makefile. Покажу, как с использованием gcc строить автоматические зависимости от .h файлов (чтобы постоянно Makefile не хачить при изменении структуры include'ов)

Добавлено через 13 минут 5 секунд
Немного по стилю написания

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void syntax_parserStmtKwLET()
{
...
    if (parser_GetToken() == TOKEN_IDENT)
    {
        int i = FindNameOverVector (::parser_CurTokenStr,defined_vars);
 
        if (i >= 0)
        {
            if (parser_GetToken() == TOKEN_DELIM_EQUAL)
            {
                defined_vars.at(i) = syntax_parserBinaryExpr ();
                defined_vars.at(i).SetInitialization(true);
            }
            else error(WRONG_LET_STATEMENT);
        }
        else error(UNDEFINED_SYMBOL, ::parser_CurTokenStr);
    }
    else error(WRONG_LET_STATEMENT);
}
Такой код тяжело читать, потому что интересующий нас фрагмент находится глубоко во вложении. При этом образное мышление у тебя линейное: сначала ДОЛЖНО быть имя переменной, затем ДОЛЖЕН быть знак "равно" затем ДОЛЖНО быть выражение

Этот же кусок можно написать с проинвертированными условиями. При этом он будет выглядет линейно. А все нелинейные вызовы error - это "плохие" случаи, которые нас не интересуют. При таком написании получается, что мы идём по прямой и отметаем в сторону ошибки. А небольшой комментарий позволяет быстро и ненапряжно оценить код

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// Разбор конструкции LET Ident "=" Expr
// Слово LET разобрано в месте вызова
void syntax_parserStmtKwLET()
{
...
    // Ident
    if (parser_GetToken() != TOKEN_IDENT)
      error(WRONG_LET_STATEMENT)
 
    // Поиск переменной по имени
    int i = FindNameOverVector (::parser_CurTokenStr,defined_vars);
 
    if (i < 0)
      error(UNDEFINED_SYMBOL, ::parser_CurTokenStr);
 
    // "="
    if (parser_GetToken() != TOKEN_DELIM_EQUAL)
      error(WRONG_LET_STATEMENT);
 
    // Expr
    defined_vars.at(i) = syntax_parserBinaryExpr ();
    defined_vars.at(i).SetInitialization(true);
}
 
Текущее время: 23:50. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru