Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.69/1283: Рейтинг темы: голосов - 1283, средняя оценка - 4.69
Временно недоступен
 Аватар для #pragma
957 / 228 / 14
Регистрация: 12.04.2009
Сообщений: 926

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

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

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

Репозиторий с проектом находится тут, там же есть возможность в браузере посмотреть историю ревизий (английский в логах весьма примитивен,комментарии и рекомендации можете писать в личку),а также скачать самый последний архив репозитория в формате .tar.gz
Если кто-то пользуется Subversion,скачать исходники можно так:
Code
1
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:
Представление выражения в двоичном дереве
*****************
Первое сообщение:
*****************
Задание(Страуструп,из книги,по готовому коду): Введите программу калькулятора и заставьте её работать.Например,при вводе
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;
31
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
20.06.2009, 20:03
Ответы с готовыми решениями:

Пишем свой интерпретатор языка BASIC
Добрый день. Я смотрю, тут на форуме была тема коллективного написания интерпретатора BASIC на языке С++. Я очень извиняюсь, но я...

Пишем свой strlen
Всем привет, вырвал часть задание из общего задание по написанию своего string. На данном этапе столкнулся с проблемой (хотел написать...

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

464
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
23.12.2009, 21:52
Студворк — интернет-сервис помощи студентам
Кстати, давно хотел сказать, но всё время забывал. Тот тест, который ты у меня взял, он у тебя коряво работает.

Вариант для моего интерпретатора

PureBasic
1
2
3
4
5
6
7
8
9
10
11
SCREEN 1
 
FOR FI=0.0 TO 639
  LET X1 = FI
  LET Y1 = 240
  LET X2 = 240 + 150.0 * SIN (FI/60)
  LET Y2 = 240 + 150.0 * COS (FI/60)
  LINE (X1,Y1) - (X2,Y2)
NEXT FI
 
SLEEP 3
Вариант для твоего интерпретатора

PureBasic
1
2
3
4
5
6
7
8
9
SCREEN 12
 
FOR FI=0 TO 639
  LET X1 = FI
  LET Y1 = 240
  LET X2 = 240 + 150 * SIN (FI/60)
  LET Y2 = 240 + 150 * COS (FI/60)
  LINE (X1,Y1) - (X2,Y2), 13
NEXT FI
Мой и твой результаты на скриншотах. Если заметишь - я в свой вариант воткнул именно плавающие значение, т.к. изначально неправильно сказал тебе о правилах неявных преобразований (мне казалось, что второй операнд всегда приводится к типу первого, а на самом деле более "узкий" приводится к более "широкому"). Правда от твоего интерпретатора я не смог добиться такой же картинки
Миниатюры
Пишем свой интерпретатор языка BASIC   Пишем свой интерпретатор языка BASIC  
1
 Аватар для AnonymC
1183 / 468 / 87
Регистрация: 23.06.2009
Сообщений: 6,390
23.12.2009, 22:33
если что надо помогу с Хеллоу ворлд!
1
 Аватар для RazorQ
591 / 357 / 16
Регистрация: 06.02.2009
Сообщений: 1,386
26.12.2009, 17:57
Я в голове прокручиваю мысли по поводу дебагера и не могу представить себе этот процесс даже в теории. В чем я уверен, так это в том, что не нужно изобретать велосипед, т.е. писать свой интерпретатор (я как минимум морально не готов писать). С другой стороны каким образом отслеживать ход программы во время интерпретации? Отдавать на съедение basin по строчке кода? А как быть с циклами и ветвлениями? Может есть какая-то поддержка со стороны самого интерпретатора? Так же я пока не знаю, откуда мне можно будет получить список переменных и как обновлять их значения.
1
Временно недоступен
 Аватар для #pragma
957 / 228 / 14
Регистрация: 12.04.2009
Сообщений: 926
26.12.2009, 18:22  [ТС]
Я так думаю,что опираться мы будем на пользовательскую отладочную печать.Некое подобие уже реализовано в виде опций командной строки --trace-act,--trace-tree,--trace-silent,а также опций в самом коде с помощью инструкции OPTION. Проблема,я так понимаю,в остановке внутри самого интерпретатора по событию,зависящему от пользователя. Я вижу такое простое решение (хотя Evg наверняка его забракует) - в командную строку перед запуском интерпретатора подаются номера строк для остановки,а также имена нужных переменных для просмотра по какому-то согласованному формату.В этом случае интерпретатор будет останавливаться на этих строках в исходнике,параллельно печатая в stdout значения нужных переменных,и ожидая ввода пользователя (любую клавишу или enter).А уже IDE будет отлавливать эти значения,и показывать их,где нужно.

>откуда мне можно будет получить список переменных и как обновлять их значения.
Это сделает сам пользователь ,и если они будут в той области видимости,то напечатаются,если нет,то нет )

Ну это дебаггер встроенный,а как делать внешний,я пока не знаю
1
 Аватар для RazorQ
591 / 357 / 16
Регистрация: 06.02.2009
Сообщений: 1,386
26.12.2009, 18:39
Хорошо. Всё же интерпретатор должен быть чистым (ИМХО), т.е. без встроенного отладчика. Но хотелось бы послушать, что скажет Evg, а я пока отложу написание дебагера.
1
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
26.12.2009, 19:04
В случае компилятора отладчик возможно делать внешним, потому как по результату работы компилятора генерится независимый (от компилятора) исполняемый файл. В этот файл складывается отладочная информация, по которой отладчик может найти соотвествие между кодом (данными) и текстом исходной программы.

В случае интерпретатора отладчик может быть только встроенным, потому как независимо выполнять программу нет возможности. Как это выглядит внешне - могу попробовать расписать. Но вот вопрос - вы когда-нибудь работали с отладчиком gdb? Внешне должно выглядеть точно так же. За счёт того, что отладчик встроен в интерпретатор, то снимается более 90% геморроя, связанного с отладкой независимого приложения

Добавлено через 9 минут
В кратце выглядит примерно так. Запускается интерпретатор со специальной опцией, по которой интерпретатор начинает работать в интерактивном режиме. Т.е. он ожидает ввода команд с консоли. Пользователь пишет в управляющей консоли "break source.bas:30", что означет поставить брейкпоинт в файле source.bas в строке 30. Далее пользователь пишет "run", что означает запуск программы. По достижении указанного места интерпретатор перестаёт исполнять программу и опять ожидает ввода. Пользователь пишет "print A", интерпретатор распечатывает значение переменной "A". Ползтватель пишет "next", интерпретатор исполняет один оператор и опять вываливается в командную строку. И т.п. IDE должна делать по большому счёту то же самое. Когда пользователь жмёт мышкой на какую-то строку, то IDE должна отправить в интерпретатор команду "break ...". Когда пользователь жмёт правой кнопкой мышки над именем переменной и выбирает "Распечатать значение", то IDE отправляет интерпреатору приказ "print ..." и перехватывает результат. По такому же принципу работают все графические отладчики: есть некий низкоуровневый отладчик, а повер него строится графическая оболочка
2
 Аватар для RazorQ
591 / 357 / 16
Регистрация: 06.02.2009
Сообщений: 1,386
26.12.2009, 19:05
Цитата Сообщение от Evg Посмотреть сообщение
Но вот вопрос - вы когда-нибудь работали с отладчиком gdb?
Постоянно. Из выше сказанного могу сделать вывод, что мне нужно всего лишь наладить обмен данными между интерпретатором и IDE. Только вот как? Сейчас я предполагаю, что все что выводиться в stdout это идет на консоль для пользователя, а то что выводиться в stderr - для программы.

Добавлено через 1 минуту
Всё понял, спасибо
1
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
26.12.2009, 19:18
Цитата Сообщение от RazorQ Посмотреть сообщение
Постоянно. Из выше сказанного могу сделать вывод, что мне нужно всего лишь наладить обмен данными между интерпретатором и IDE. Только вот как? Сейчас я предполагаю, что все что выводиться в stdout это идет на консоль для пользователя, а то что выводиться в stderr - для программы.
Скажем так, интерпретаторов я никогда не писал, но пока в теории выглядит именно так. Всегда можно сделать дополнительную опцию (означающую запуск из-под IDE), а по этой опции весь вывод интерпретатора будет делаться под IDE, а не под человека (что упростит в IDE синтаксический разбор всей этой писанины, а так же появится свобода вы выдаче сообщений пользователю без боязни того, что это сломает работу IDE)

Как вариант вместо stdout, stderr можно открывать дополнительные файловые потоки, опять-таки чтобы не путать печати программы с выводом интерпретатора
1
 Аватар для RazorQ
591 / 357 / 16
Регистрация: 06.02.2009
Сообщений: 1,386
27.12.2009, 16:17
Слушайте, а как называется ваш язык программирования? Я не стал перечитывать всю тему, может вы уже говорили об этом. Просто я всегда называю его Basic (именно так, а не BASIC), может я ошибаюсь.
1
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
27.12.2009, 18:03
BASIC расшифровывается что-то типа "the Beginners All-sourpose Symbolic Instruction Code". Т.е. авторы взяли слово "basic" и сделали из него аббревиатуру. Поэтому провально писать все буквы заглавными. Диалектов бэйсика существует целая куча (грубо говоря, каждый разработчик делал немного по-своему). За основу мы брали Q-BASIC.
1
 Аватар для RazorQ
591 / 357 / 16
Регистрация: 06.02.2009
Сообщений: 1,386
27.12.2009, 18:36
Выкладываю наработки. Версия не совсем в рабочем состоянии, но я уже выбился из сил искать ошибку! Прошу откомпилировать, запустить и выключить. А потом рассказать мне о впечатлениях.
Вложения
Тип файла: zip Basin-IDE.zip (109.8 Кб, 33 просмотров)
1
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
27.12.2009, 20:57
У меня пока отсутсвует линукс
1
Временно недоступен
 Аватар для #pragma
957 / 228 / 14
Регистрация: 12.04.2009
Сообщений: 926
28.12.2009, 07:05  [ТС]
Почему-то у меня не скомпилировалось.
Листинг ошибок (после того,как выполнил qmake,а затем make)
Code
1
2
3
4
5
6
7
8
9
10
11
12
$ make
/usr/bin/uic-qt4 mainwindow.ui -o ui_mainwindow.h
/usr/bin/uic-qt4 finddialog.ui -o ui_finddialog.h
Warning: name layoutWidget is already used
g++ -c -pipe -O2 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++ -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4 -I. -I. -I. -o highlighter.o highlighter.cpp
g++ -c -pipe -O2 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++ -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4 -I. -I. -I. -o main.o main.cpp
In file included from mainwindow.h:9,
                 from main.cpp:5:
ui_mainwindow.h: In member function ‘void Ui_MainWindow::setupUi(QMainWindow*)’:
ui_mainwindow.h:88: error: ‘class QAction’ has no member named ‘setPriority’
ui_mainwindow.h:88: error: ‘NormalPriority’ is not a member of ‘QAction’
make: *** [main.o] Error 1
0
 Аватар для RazorQ
591 / 357 / 16
Регистрация: 06.02.2009
Сообщений: 1,386
28.12.2009, 10:09
Почему-то у меня не скомпилировалось.
Открываем mainwindow.ui в дизайнере -> выделяем кнопочку "Новый" или в списке действий выбираем newAct -> свойство priority устанавливаем по умолчанию (кнопочка похожая на Enter в свойствах)
0
Временно недоступен
 Аватар для #pragma
957 / 228 / 14
Регистрация: 12.04.2009
Сообщений: 926
28.12.2009, 14:50  [ТС]
А можно как-то без дизайнера обойтись? Я просто хочу скомпилить проект в консоли.. Ты скажи,что в исходнике поменять,я поменяю,или патч сделай,а то я что-то не въеду с этими кнопочками.
0
 Аватар для RazorQ
591 / 357 / 16
Регистрация: 06.02.2009
Сообщений: 1,386
28.12.2009, 14:53
#pragma, в таком случае просто удали строчку 88 из файла ui_mainwindow.h
1
 Аватар для RazorQ
591 / 357 / 16
Регистрация: 06.02.2009
Сообщений: 1,386
28.12.2009, 14:59
Я тут на коленке подправил
Вложения
Тип файла: zip Basin-IDE.zip (113.0 Кб, 27 просмотров)
1
Временно недоступен
 Аватар для #pragma
957 / 228 / 14
Регистрация: 12.04.2009
Сообщений: 926
28.12.2009, 16:19  [ТС]
Посмотрел.Вроде бы ничего,красиво.Почему-то LINE идёт курсивом.Может,возьмешь регекспы из моей версии? Там впринципе почти готово было (ну может пару слов зарезервированных не было). Когда показывается окно с ошибками,неплохо бы,чтобы оно было поменьше,а то немного великовато на фоне общего размера окна.Я в своей версии не смог его сделать узкого размера,но так,чтобы его можно было растягивать.Поэтому сделал просто узкий фиксированный размер.У нас ведь интерпретатор показывает только одну ошибку за раз,и столько места не нужно. Можно ещё сделать выделение строки с ошибкой другим цветом,чтобы подчеркнуть,что что-то не так.
Ну и если можно,сделать сохранение файла настроек для Basin-IDE в ту же папку,где лежит проект,и чтобы ничего не сохранялось в домашнюю папку,а то я заметил,сохраняется какой-то .conf файл: зачем?
У меня ещё такой вопрос есть: а для чего вообще эти ui файлы? Что они дают? Я без них как-то обходился,но в принципе и дизайнером не пользовался тоже.
0
 Аватар для RazorQ
591 / 357 / 16
Регистрация: 06.02.2009
Сообщений: 1,386
28.12.2009, 16:29
Цитата Сообщение от #pragma Посмотреть сообщение
Почему-то LINE идёт курсивом
Это потому, что LINE - функция, а все функции я подсвечиваю по другому. Но хозяин - барин, как скажешь, так и сделаю.
Цитата Сообщение от #pragma Посмотреть сообщение
ну может пару слов зарезервированных не было
Я брал из файла SYNTAX. Если можно, то весь список в студию.
Цитата Сообщение от #pragma Посмотреть сообщение
Когда показывается окно с ошибками,неплохо бы,чтобы оно было поменьше,а то немного великовато на фоне общего размера окна.
Это да. Исправим
Цитата Сообщение от #pragma Посмотреть сообщение
Можно ещё сделать выделение строки с ошибкой другим цветом,чтобы подчеркнуть,что что-то не так.
Я пробовал красный цвет, но он получается очень яркий и за ним не видно строки. Но поэкспериментирую.
Ну и если можно,сделать сохранение файла настроек для Basin-IDE в ту же папку,где лежит проект,и чтобы ничего не сохранялось в домашнюю папку,а то я заметил,сохраняется какой-то .conf файл: зачем?
Я сохраняю размер окна и позицию. Для этого использую QSettings, который на линухе сохраняет в домашнюю папку, а на Виндовсе в реестр. Впрочем, я сам не против сделать сохранение настроек в локальную папку.

Добавлено через 4 минуты
Я тут статейку нашел. Там описывается создание интерпретатора языка Си. Собственно зачем даю ссылку - так хорошо расписан разбор и представление функций. http://lord-n.narod.ru/downloa... o_C/VI.htm
1
Временно недоступен
 Аватар для #pragma
957 / 228 / 14
Регистрация: 12.04.2009
Сообщений: 926
28.12.2009, 16:47  [ТС]
Насчёт яркости,я так делал (тоже стырил из примеров):
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
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
28.12.2009, 16:47

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

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
320
Закрытая тема Создать тему
Новые блоги и статьи
сукцессия 29. Переход от одних деревьев на другие делать более или менее вероятностным?
anaschu 12.07.2026
Насколько смена типов микоризы — исключительное событие в двухвековой сукцессии? Оценка вероятности в пространстве параметров В текущей версии модели успешно реализован ключевой механизм. . .
сукцессия 27. Думаю, как переделывать уже написанную статью с планами на сукцессию.
anaschu 12.07.2026
Анализ соответствия модели требованиям Реализованные компоненты: Механизм закисления почвы через протонную помпу Конкуренция между типами микориз pH как триггер сукцессии C/ P соотношение. . .
Сукцессия 26. Мат модель создана.
anaschu 12.07.2026
Модель смены растительных сукцессий посредством управления грибами работает внутри небольшой ячейки почвы, восстанавливающейся после пожара, где ненадолго бывшее царство хвойных снова захватили. . .
Решил проблему с ошибкой пагинации сообщений с сервера на алгоритме обхода дерева "Эстафета хвоста".
Hrethgir 12.07.2026
Проблема была в том, что удалялась именно новая кнопка, а не старая. Ни один ИИ не обнаружил это, а сам я смог только когда с работой стало попроще и когда заставил работать будущее автономное. . .
сукцессия 25. Хронология ошибок
anaschu 12.07.2026
# От 50-тонного гриба до устойчивого леса: хроника ошибок при построении модели вековой сукцессии микоризы ## О чём эта статья В процессе построения ОДУ-модели (система дифференциальных. . .
сукцессия 24. Промежуточное общее описание модели
anaschu 12.07.2026
Хендофф: модель АМ→ЭКМ сукцессии микоризы (ризосфера, 50 лет) Содержание проекта Симуляция вековой (50 лет) экологической сукцессии в почве леса Основные участники: АМ-гриб, ЭКМ-гриб,. . .
сукцессия 23. Более физиологичная физиология, более экологичная экология, более диффурные диффуры.
anaschu 12.07.2026
Что реально нашли и починили за эти 5 часов Правило Линдемана (КПД конверсии сахара в тело, kEff) — раньше 100% полученного углерода шло прямо в биомассу гриба; теперь только kEff=0. 5 (после. . .
сукцессия 22. От артефактов к физиологии: калибровка агентной модели грибной сукцессии для воспроизведения сезонной динамики и pH-плато
anaschu 11.07.2026
Аннотация В данной работе представлена калибровка агентной модели динамики грибных сообществ (fungal-succession), направленная на устранение нефизичных артефактов (коллапс биомассы, мгновенное. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru