С Новым годом! Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 1509, средняя оценка - 4.80
#pragma
Временно недоступен
954 / 225 / 6
Регистрация: 12.04.2009
Сообщений: 921
#1

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

20.06.2009, 20:03. Просмотров 193959. Ответов 464
Метки нет (Все метки)

*****************
Благодаря форуму и Evg в частности интерпретатор развивается, потихоньку превращаясь в простенький интерпретатор QBASIC.
Некоторые из самых старых версий сохранились в теме и ссылки на них будут добавлены в это сообщение,а также ссылки на другие темы,связанные с этой.

Репозиторий с проектом находится тут, там же есть возможность в браузере посмотреть историю ревизий (английский в логах весьма примитивен,комментарии и рекомендации можете писать в личку),а также скачать самый последний архив репозитория в формате .tar.gz
Если кто-то пользуется Subversion,скачать исходники можно так:
Код
svn co https://basin.svn.sourceforge.net/svnroot/basin basin
Эти темы возникли в результате моих вопросов по ходу написания:
Технический приём для формирования согласованных данных
Makefile: как с использованием gcc строить автоматические зависимости от .h файлов?
Вопрос по svn (Subversion)
Создание системы тестирования ПО.
Вопрос про разные реализации бэйсиков
Можно ли выразить порядковый номер элемента массива через индексы?
[C++] Какие флаги указать линкеру для компиляции программы?
Как можно определить переменную в файле configure.in,чтобы её можно было использовать в Makefile?
Странный SIGSEGV, или что зависит от порядка написания интерфейса класса
[C++]Можно ли как-то указать в Makefile,чтобы часть файлов компилировал компилятор C?
Альтернативная версия интерпретатора от Evg на C
Это простая реализация разбора выражений, написанная Evg на C:
Представление выражения в двоичном дереве
*****************
Первое сообщение:
*****************
Задание(Страуструп,из книги,по готовому коду): Введите программу калькулятора и заставьте её работать.Например,при вводе
C++
1
2
r = 2.5
area = pi*r*r
Программа калькулятора выведет:
C++
1
2
2.5
19.635
Получили такой код:
LexicalAnalyzer.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// LexicalAnalyzer.h
#ifndef LEXICALANALYZER_H_INCLUDED
#define LEXICALANALYZER_H_INCLUDED
 
#include <cctype>
#include <string>
#include <map>
#include <iostream>
 
enum Token_value {
    NAME,       NUMBER,      END,
    PLUS = '+', MINUS = '-', MUL = '*', DIV = '/',
    PRINT = ';',ASSIGN = '=',LP = '(',  RP = ')'
};
extern Token_value curr_tok;
extern std::map<std::string,double>table;
extern int no_of_errors;
 
Token_value get_token();
 
double expr(bool);
double term (bool);
double prim (bool);
int error(const std::string&);
 
#endif // LEXICALANALYZER_H_INCLUDED

LexicalAnalyzer.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
// LexicalAnalyzer.cpp
#include "LexicalAnalyzer.h"
 
 
std::map<std::string,double>table;
Token_value curr_tok=PRINT;
 
double expr (bool get)
{
    double left = term(get);
 
    for (;;)
        switch (curr_tok) {
            case PLUS:
                 left += term(true);
            break;
            case MINUS:
                 left-= term(true);
            break;
            default:
                 return left;
        }
}
 
double term (bool get)
{
    double left = prim (get);
 
    for (;;)
        switch (curr_tok) {
            case MUL:
                 left*=prim(true);
            break;
            case DIV:
                 if (double d = prim (true)) {
                     left /= prim (true);
                     break;
                 }
                 return error("Деление на ноль");
            default:
                 return left;
        }
}
 
double number_value;
std::string string_value;
 
double prim (bool get)
{
    if (get) get_token();
    switch (curr_tok){
        case NUMBER:{
            double& v = number_value;
            get_token();
            return v;
        }
        case NAME:{
            double& v = table[string_value];
            if (get_token()==ASSIGN) v = expr(true);
            return v;
        }
        case MINUS:
            return -prim(true);
        case LP:{
            double e = expr(true);
            if (curr_tok!=RP) return error("Ожидалась )");
            get_token();
            return e;
        }
        default:
            return error("Ожидалось первичное выражение");
    }
}
 
Token_value get_token()
{
    char ch = 0;
 
    do {
        if (!std::cin.get(ch)) return curr_tok = END;
    } while (ch!='\n'&&isspace(ch));
 
    switch (ch) {
        case 0:
             return curr_tok = END;
        case ';':case '\n':
             return curr_tok = PRINT;
        case '*':case'/':case '+':case '-':case '(':case ')':case '=':
             return Token_value(ch);
        case '0':case '1':case '2':case '3':case '4' :
        case '5':case '6':case '7':case '8':case '9':case '.':
             std::cin.putback(ch);
             std::cin>>number_value;
             return curr_tok=NUMBER;
        default:
             if (isalpha(ch)) {
                 string_value = ch;
                 while (std::cin.get(ch)&&isalnum(ch)) string_value.push_back(ch);
                 std::cin.putback(ch);
                 return curr_tok = NAME;
             }
             error ("Неправильная лексема");
             return curr_tok = PRINT;
    }
}
int no_of_errors=0;
int error (const std::string& s)
{
    no_of_errors++;
    std::cerr<<"Ошибка: "<<s<<'\n';
    return no_of_errors;
}

main.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// main.cpp
#include "LexicalAnalyzer.h"
 
 
int main()
{
    table["pi"]=3.1415926535897932385;
    table["e"]=2.7182818284590452354;
    while (std::cin) {
        get_token();
        if (curr_tok==END) break;
        if (curr_tok==PRINT) continue;
        std::cout<<expr(false)<<'\n';
    }
    return no_of_errors;
}

Анализатор-то работает,но конечное значение не вычисляется.Более того,если вводим
C++
1
a = 3 + 6
,то получаем "a", равное первому элементу в выражении,то есть 3.В чём логическая ошибка данной программы?С этими каскадными вызовами она слегка запутана.Уверен,что кто-то уже делал это задание.

Добавлено через 2 часа 5 минут 30 секунд
Пришлось решать влоб с дебаггером.У Страуструпа опечатка (или намеренная ошибка,что более вероятно ) Вот в этом куске кода в функции get_token():
C++
1
2
        case '*':case'/':case '+':case '-':case '(':case ')':case '=':
             return Token_value(ch);
Нехватает смены значения curr_tok,что и приводит к ошибочной работе.
C++
1
2
        case '*':case'/':case '+':case '-':case '(':case ')':case '=':
             return curr_tok=Token_value(ch);
Теперь всё пашет,всем спасибо,вопрос можно считать закрытым,но есть вопрос поважнее: В функциях prim и term возвращается int при ошибке,но ведь они имеют тип double,как вообще это работает?Происходит неявное преобразование типа,так?Мне интересно,почему Страуструп прибег к такому способу,это распространённая практика?

Добавлено через 16 минут 19 секунд
И ещё опечатка была
C++
1
2
3
                 if (double d = prim (true)) {
                     left /= d;// было left /= prim (true)
                     break;
30
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
20.06.2009, 20:03
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Пишем свой интерпретатор языка BASIC (C++):

Пишем свой чекер - C++
Я хочу написать свой чекер, но не знаю с чего начать? Кто знает основные принцип работы чекеров прошу объясните.

пишем свой троян с нуля - C++
Всем привет)))соглашусь, что изобретаю велосипед, но хочется сделать все своими ручками не прибегая к open source и т.п. для повышения...

Пишем свой класс, спецификатор доступа protected - C++
Всем привет! Из книги Р. Лафоре относительно спецификатора доступа protected: Далее пишется следующее: Возникает вопросы:...

Не удается откомпилировать интерпретатор М-языка - C++
Задача: взять интерпретатор М-языка на сайте http://cmcmsu.no-ip.info/2course/model.lang.parser.sample.htm и переработать его, добавив в...

Интерпретатор небольшого языка программирования на С++ - C++
Здравствуйте, уважаемые форумчане! Я тут где-то год назад прочитал тему Evg и #pragma о создании интерпретатора, меня эта тема очень...

Написать Интерпретатор Программного Языка(собственного) - C++
Здраствуйте! Кто знает C++ помогите пожалуйста с реализацией данного задания!!! Пожалуйста, очень надо. сроки поджимают. Есть...

464
RazorQ
581 / 348 / 9
Регистрация: 06.02.2009
Сообщений: 1,386
28.12.2009, 14:53 #316
#pragma, в таком случае просто удали строчку 88 из файла ui_mainwindow.h
1
RazorQ
581 / 348 / 9
Регистрация: 06.02.2009
Сообщений: 1,386
28.12.2009, 14:59 #317
Я тут на коленке подправил
1
Вложения
Тип файла: zip Basin-IDE.zip (113.0 Кб, 26 просмотров)
#pragma
Временно недоступен
954 / 225 / 6
Регистрация: 12.04.2009
Сообщений: 921
28.12.2009, 16:19  [ТС] #318
Посмотрел.Вроде бы ничего,красиво.Почему-то LINE идёт курсивом.Может,возьмешь регекспы из моей версии? Там впринципе почти готово было (ну может пару слов зарезервированных не было). Когда показывается окно с ошибками,неплохо бы,чтобы оно было поменьше,а то немного великовато на фоне общего размера окна.Я в своей версии не смог его сделать узкого размера,но так,чтобы его можно было растягивать.Поэтому сделал просто узкий фиксированный размер.У нас ведь интерпретатор показывает только одну ошибку за раз,и столько места не нужно. Можно ещё сделать выделение строки с ошибкой другим цветом,чтобы подчеркнуть,что что-то не так.
Ну и если можно,сделать сохранение файла настроек для Basin-IDE в ту же папку,где лежит проект,и чтобы ничего не сохранялось в домашнюю папку,а то я заметил,сохраняется какой-то .conf файл: зачем?
У меня ещё такой вопрос есть: а для чего вообще эти ui файлы? Что они дают? Я без них как-то обходился,но в принципе и дизайнером не пользовался тоже.
0
RazorQ
581 / 348 / 9
Регистрация: 06.02.2009
Сообщений: 1,386
28.12.2009, 16:29 #319
Цитата Сообщение от #pragma Посмотреть сообщение
Почему-то LINE идёт курсивом
Это потому, что LINE - функция, а все функции я подсвечиваю по другому. Но хозяин - барин, как скажешь, так и сделаю.
Цитата Сообщение от #pragma Посмотреть сообщение
ну может пару слов зарезервированных не было
Я брал из файла SYNTAX. Если можно, то весь список в студию.
Цитата Сообщение от #pragma Посмотреть сообщение
Когда показывается окно с ошибками,неплохо бы,чтобы оно было поменьше,а то немного великовато на фоне общего размера окна.
Это да. Исправим
Цитата Сообщение от #pragma Посмотреть сообщение
Можно ещё сделать выделение строки с ошибкой другим цветом,чтобы подчеркнуть,что что-то не так.
Я пробовал красный цвет, но он получается очень яркий и за ним не видно строки. Но поэкспериментирую.
Ну и если можно,сделать сохранение файла настроек для Basin-IDE в ту же папку,где лежит проект,и чтобы ничего не сохранялось в домашнюю папку,а то я заметил,сохраняется какой-то .conf файл: зачем?
Я сохраняю размер окна и позицию. Для этого использую QSettings, который на линухе сохраняет в домашнюю папку, а на Виндовсе в реестр. Впрочем, я сам не против сделать сохранение настроек в локальную папку.

Добавлено через 4 минуты
Я тут статейку нашел. Там описывается создание интерпретатора языка Си. Собственно зачем даю ссылку - так хорошо расписан разбор и представление функций. http://lord-n.narod.ru/download/book...pr_po_C/VI.htm
1
#pragma
Временно недоступен
954 / 225 / 6
Регистрация: 12.04.2009
Сообщений: 921
28.12.2009, 16:47  [ТС] #320
Насчёт яркости,я так делал (тоже стырил из примеров):
C++
1
2
3
     QList<QTextEdit::ExtraSelection> extraSelections;
     QTextEdit::ExtraSelection selection;
     QColor lineColor = QColor(Qt::red).lighter(170);
Оперируя числом,меняем яркость.
По идее функции тоже надо выделять как ключевые слова,разве что цвет чуть чуть поменять.LINE ведь у нас идёт как Statement,а вот встроенные функции,которые учавствуют в выражениях,их бы надо по другому.
PureBasic
1
2
LET
LINE
Видишь,даже тут выделяется одинаково )
Вот список выделяемых слов.(могут быть забытые,но по идее все слова из parser.cpp в интерпретаторе нужно как-то выделять,кроме встроенных функций для выражений)
список зарезервированных слов
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
       parser_ResWord[ "LET"  ] = parser_TokenType(TOKEN_KW_LET);
       parser_ResWord["PRINT" ] = parser_TokenType(TOKEN_KW_PRINT);
       parser_ResWord["INPUT" ] = parser_TokenType(TOKEN_KW_INPUT);
       parser_ResWord[ "DIM"  ] = parser_TokenType(TOKEN_KW_DIM);
       parser_ResWord[  "TO"  ] = parser_TokenType(TOKEN_KW_TO);
       parser_ResWord["OPTION"] = parser_TokenType(TOKEN_KW_OPTION);
       parser_ResWord[  "IF"  ] = parser_TokenType(TOKEN_KW_IF);
       parser_ResWord[ "THEN" ] = parser_TokenType(TOKEN_KW_THEN);
       parser_ResWord[ "ELSE" ] = parser_TokenType(TOKEN_KW_ELSE);
       parser_ResWord["ELSEIF"] = parser_TokenType(TOKEN_KW_ELSEIF);
       parser_ResWord["WHILE" ] = parser_TokenType(TOKEN_KW_WHILE);
       parser_ResWord[ "WEND" ] = parser_TokenType(TOKEN_KW_WEND);
       parser_ResWord[ "FOR"  ] = parser_TokenType(TOKEN_KW_FOR);
       parser_ResWord[ "STEP" ] = parser_TokenType(TOKEN_KW_STEP);
       parser_ResWord[ "NEXT" ] = parser_TokenType(TOKEN_KW_NEXT);
       parser_ResWord[  "DO"  ] = parser_TokenType(TOKEN_KW_DO);
       parser_ResWord[ "UNTIL"] = parser_TokenType(TOKEN_KW_UNTIL);
       parser_ResWord[ "FUNC" ] = parser_TokenType(TOKEN_KW_FUNC);
       parser_ResWord["BEGIN" ] = parser_TokenType(TOKEN_KW_BEGIN);
       parser_ResWord[ "END"  ] = parser_TokenType(TOKEN_KW_END);
       parser_ResWord[ "LOOP" ] = parser_TokenType(TOKEN_KW_LOOP);
       parser_ResWord["RETURN"] = parser_TokenType(TOKEN_KW_RETURN);
       parser_ResWord[ "GOTO" ] = parser_TokenType(TOKEN_KW_GOTO);
       parser_ResWord[ "BASE" ] = parser_TokenType(TOKEN_KW_BASE);
       parser_ResWord["TRACE" ] = parser_TokenType(TOKEN_KW_TRACE);
       parser_ResWord["SCREEN"] = parser_TokenType(TOKEN_KW_SCREEN);
       parser_ResWord["PRESET"] = parser_TokenType(TOKEN_KW_PRESET);
       parser_ResWord[ "LINE" ] = parser_TokenType(TOKEN_KW_LINE);
       parser_ResWord["CIRCLE"] = parser_TokenType(TOKEN_KW_CIRCLE);
       parser_ResWord[ "CLS"  ] = parser_TokenType(TOKEN_KW_CLS);
       parser_ResWord[ "BEEP" ] = parser_TokenType(TOKEN_KW_BEEP);
       parser_ResWord["CLEAR" ] = parser_TokenType(TOKEN_KW_CLEAR);
       parser_ResWord[ "SIN"  ] = parser_TokenType(TOKEN_KW_SIN);
       parser_ResWord[ "COS"  ] = parser_TokenType(TOKEN_KW_COS);
       parser_ResWord[ "TAN"  ] = parser_TokenType(TOKEN_KW_TAN);
       parser_ResWord[ "ATN"  ] = parser_TokenType(TOKEN_KW_ATN);
       parser_ResWord[ "VAL"  ] = parser_TokenType(TOKEN_KW_VAL);
       parser_ResWord[ "STR$" ] = parser_TokenType(TOKEN_KW_STR);
       parser_ResWord[ "LEN"  ] = parser_TokenType(TOKEN_KW_LEN);
       parser_ResWord[ "SQR"  ] = parser_TokenType(TOKEN_KW_SQR);
       parser_ResWord[ "ABS"  ] = parser_TokenType(TOKEN_KW_ABS);
       parser_ResWord["INSTR" ] = parser_TokenType(TOKEN_KW_INSTR);
       parser_ResWord[ "LEFT$"] = parser_TokenType(TOKEN_KW_LEFT);
       parser_ResWord["RIGHT$"] = parser_TokenType(TOKEN_KW_RIGHT);
       parser_ResWord[ "MID$" ] = parser_TokenType(TOKEN_KW_MID);
 
       // Reserved words - Typenames  //////////////////////////////////////////
       parser_ResType[ "INT"  ] = parser_TokenType(TOKEN_TYPE_INT);
       parser_ResType[ "LNG"  ] = parser_TokenType(TOKEN_TYPE_LINT);
       parser_ResType[ "SNG"  ] = parser_TokenType(TOKEN_TYPE_FLOAT);
       parser_ResType[ "DBL"  ] = parser_TokenType(TOKEN_TYPE_DOUBLE);
       parser_ResType[ "STR"  ] = parser_TokenType(TOKEN_TYPE_STRING);
       parser_ResType[ "VOID" ] = parser_TokenType(TOKEN_TYPE_VOID);
1
RazorQ
581 / 348 / 9
Регистрация: 06.02.2009
Сообщений: 1,386
28.12.2009, 16:55 #321
Ещё, я хочу сделать так: программист набирает ключевое слово, ставит пробел, а слово преобразовывается к одному стилю. Допустим, я набираю PrInT, а IDE меняет на Print. Всё это сделать, само собой, опционально. Как такая идея? И по поводу стиля: лично мне нравиться набирать зарезервированные слова с большой буквы, а здесь я вижу, что всё в верхнем регистре. Наверное, тоже надо вводить опцию.
1
#pragma
Временно недоступен
954 / 225 / 6
Регистрация: 12.04.2009
Сообщений: 921
28.12.2009, 17:02  [ТС] #322
Интерпретатор переводит все символы в верхний регистр перед использованием. Можно подражать той IDE что была для QBASIC - там текст переводился в верхний регистр,что бы пользователь не писал. Да,можно сделать опционально с разными стилями.
0
Evg
Эксперт CАвтор FAQ
18383 / 6431 / 441
Регистрация: 30.03.2009
Сообщений: 17,852
Записей в блоге: 28
28.12.2009, 22:50 #323
По поводу синтаксической подсветки. Чтобы интерпретатор знал поменьше о языке программирования, я бы в интерпретое завл специальную опцию, по которой он распечатывает в stdout все regexp'ы. Я толком не знаю, как это выглядит, то наверное в текстовом виде это представимо. И IDE бы дёргала интерпретатор и подхватывала этот набор.

Второй вариант - в процессе сборки интерпретатора генерить некий конфиг-файл (файл *.h или в любой другой форме, в которой это можно вкомпилить в исходник), в котором были бы описаны regexp'ы, а при сборке IDE этот файл подцеплять. Этот вариант хорош тем, что в код придётся затаскивать меньше всякого гавна. Но, если делать всё по-хорошему (когда мы формально имеем отдельно исходники интерпретатора, а отдельно исходники IDE), то в комплект поставки интерпреатора должен входить этот конфиг файл. Чтобы теоретические (гипотетические) IDE от других разработчиков лучше состыковывались с интерпретатором. Да и вообще описание всего интерфейса (с какими опциями запускать интерпретатор, как фильтровать выдачу и т.п.) можно построить на базе этих файлов, генерируемых в процессе сборки интерпретатора. Это сильно облегчит жизнь, когда надо будет в интерпреатторе что-то менять.

Добавлено через 26 минут
Цитата Сообщение от RazorQ Посмотреть сообщение
Я тут на коленке подправил
Заведи себе привычку архивировать проект вместе с головным каталогом. Потому как все, кто скачиывает твой файл, вынуждены каталог создавать ручками

Добавлено через 5 минут
При печати ошибки внизу у тебя пишется только текст ошибки. Хотя для порядку надо бы печатать имя файла и номер строки. Или на худой конец слово Error, а то нифига не понятно, что это за окошко внизу такое. Для порядку по опции можно печатать строку запуска интерпретатора (чтобы пользователь знал, как это повторить без IDE).

Сделал код с ошибкой. Запустил. Оно сломалось и строка подсветилось - тут всё нормально. Ошибку исправил, запустил, но текст ошибки в нижнем окне остался. Перед каждым запуском нижнее окно надо чистить

Добавлено через 2 минуты
Когда после ошибочного запуска интерпретатора редактор позиционируется на строке с ошибкой, то строку было бы лучше выделать красным вместо синего (у людей врде что-то похожее сделано, только не помню точно, как именно)
2
RazorQ
581 / 348 / 9
Регистрация: 06.02.2009
Сообщений: 1,386
03.01.2010, 18:34 #324
Позволю себе несколько замечаний по языку. К следующим заключениям я пришел после непосредственного использования языка и они (заключения) только лишь ИМХО:
  • У цикла while должно быть завершение аналогичное остальным конструкциям, т.е. end while. Я понимаю, что это связано с определенными трудностями, но тем не менее минус одно ключевое слово. Язык ведь для начинающих.
  • Названия типов. Вроде всё в порядке, но обрубки (извиняюсь, если что) никуда не годятся. Сейчас язык удобен для интерпретатора, но я считаю что в последствии его будут использовать. Так вот, "INT" "LNG" "SNG" "DBL" "STR" "VOID" - не подходят, это ж Basic, а не C++. Особенно void - его вообще нет в basic'е. Все остальные назвать полными именами: Integer, Long, Short, Double, String
  • Помойму, вместо func лучше использовать sub или function. Но первое предпочтительнее.
  • Что такое UNTIL? Или оно не поддерживается?
  • Объявлять переменные мне нравиться в стиле Microsoft: Dim varName As Integer = 20
    Слово Dim уже есть, добавить только As и будет очень элегантно смотреться.
Честно, я не смотрел документацию по Q-Basic - было интересно проверить интерпретатор на дружелюбность и интуитивность.
но я считаю что в последствии его будут использовать
Я буду первый на очереди Честно. Мне племянника надо подтягивать, сам люблю Basic - с ним можно расслабиться.
1
#pragma
Временно недоступен
954 / 225 / 6
Регистрация: 12.04.2009
Сообщений: 921
04.01.2010, 09:49  [ТС] #325
>У цикла while должно быть завершение аналогичное остальным конструкциям, т.е. end while. Я понимаю, что это связано с определенными трудностями, но тем не менее минус одно ключевое слово. Язык ведь для начинающих.
Я делал по тому,что написано тут и тут,там сказано,что окончание для while - это WEND.
Про типы :сами названия в строковом представлении в интерпретаторе не используются.Это что-то древнее,которое придётся править.Тип VOID только для внутреннего представления,я его сделал как некий костыль,и значения этого типа могут принимать любой другой тип.Это по идее всего лишь флажок,обозначающий только что созданный объект Value.
Слово FUNC тоже пережиток прошлых попыток с функциями,их было много.
UNTIL: По идее цикл с DO должен выглядеть как
PureBasic
1
2
3
DO
  ...
LOOP UNTIL
А у меня пока так
PureBasic
1
2
3
DO
  ...
WHILE
Не помню,то ли я прочитал где-то об этом варианте,то ли сам выдумал,но это одно из TODO которые надо доделывать.Ключевые слова у меня добавляются просто,поэтому это одно из древних.
Для DIM тоже надо доделывать тот вариант,про который ты пишешь.
Пока я пытаюсь перевести всю программу на классы,там такая каша,ещё поиск по стекам добавился,приходится делать правки вслепую,без компиляции.Потом,когда всё заработает,надо будет,конечно,исправить мелочи выше.
1
RazorQ
581 / 348 / 9
Регистрация: 06.02.2009
Сообщений: 1,386
04.01.2010, 11:01 #326
Всё. Вопросов нет. Спасибо.
1
#pragma
Временно недоступен
954 / 225 / 6
Регистрация: 12.04.2009
Сообщений: 921
18.03.2010, 23:18  [ТС] #327
Меняю построение синтаксиса DIM всвязи с запланированным добавлением функций (нужно добавить SHARED и[ AS type]),возник вопрос:
DIM ведь по сути ничего не делает,все части этой инструкции или имена переменных,или константы (в случае с измерениями массивов).
С другой стороны,в DIM у меня присутствует некий элемент runtime - именно в этот момент во время интерпретации представления придаются свойства массиву и его элементы обнуляются. Вот я не знаю,стоит ли убрать DIM как часть представления вообще и во время построения содавать все переменные и массивы,часть из этих функций возложив на конструкторы? Или создание переменных следует считать runtime частью ? Моя туманная логика подсказывает,что переменные стоит создавать по мере их встречи в программе.
0
Evg
Эксперт CАвтор FAQ
18383 / 6431 / 441
Регистрация: 30.03.2009
Сообщений: 17,852
Записей в блоге: 28
18.03.2010, 23:40 #328
Как оно устроено в реальных бэйскиах - я даже не знаю. Я у себя делал так, что DIM - это НЕ statement, а declaration. Т.е. на этапе синтаксического разбора сразу строился тип и переменная этого типа. Но насколько помню, на старых "продвинутых" версиях бэйсиков типа Yamaha в качестве размерности можно было задавать НЕ константу. Но я не помню, насколько это было свободным. Т.е. обязана ли была переменная (выражение) выступающая в качестве размерности массива на момент определения DIM иметь вычислимое значение. По факту во многих программах было что-то типа "LET N=10 ; DIM A(N)" и всё это объявлялось в начале программы. Так что тут надо курить документацию по бэйсику

Что такое SHARED и AS я тоже не знаю. Но из всего описания этого барахла в принципе можно будет понять, массив появляется в runtime или статически (на этапе трансляции)
1
RazorQ
581 / 348 / 9
Регистрация: 06.02.2009
Сообщений: 1,386
21.03.2010, 11:06 #329
Извиняюсь, за столь долгую отлучку, но всё как-то не получалось. По сравнению с предыдущей версией эта много нового не внесла. Цель которую я преследовал: вытрясти максимально много ошибок. Так сказать, сделать базу на основе которой можно будет развивать программу. И я считаю, что можно присвоит этой программе версию 0.1
2
Вложения
Тип файла: zip Basin-IDEv01.zip (138.0 Кб, 15 просмотров)
niXman
Эксперт С++
3139 / 1451 / 49
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
21.03.2010, 12:26 #330
Пересмотрел код Basin-IDE.
Обнаружил лишний new в BasinApplication::newMainWindow()
глянул далее, а там их полно) остальные оставил так.
- "нафига столько new ?"
2
Вложения
Тип файла: zip Basin-IDE.zip (114.0 Кб, 15 просмотров)
21.03.2010, 12:26
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
21.03.2010, 12:26
Привет! Вот еще темы с ответами:

Написать интерпретатор программного языка -помощь - C++
Здраствуйте! Ребят, кто хорошо разбирается в C++ помогите пожалуйста с реализацией данного задания или хотя бы подтолкните к решению,...

Интерпретатор/компилятор ассемблер-подобного языка - C++
Привет! Чую, что изобрёл велисипед, даже скорее велопарк, но всё же, поделюсь: Некоторое время назад начал изучать кресты, в целом...

Интерпретатор музыки стандарта BASIC PLAY на С++ - C++
У кого нибудь есть функция или класс, который сможет воспроизводить в С++ напрямую музыкальные строки, записанные в стандарте оператора...

Задание: разработать "Интерпретатор языка". С чего начать? - C++
Здравствуйте, вручили темку на курсовик, ну точнее как вручили, не успел взять то, что хотел - пришлось брать то, что осталось. Плоховато...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
330
Закрытая тема Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.