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

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

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

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

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

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

Репозиторий с проектом находится тут, там же есть возможность в браузере посмотреть историю ревизий (английский в логах весьма примитивен,комментарии и рекомендации можете писать в личку),а также скачать самый последний архив репозитория в формате .tar.gz
Если кто-то пользуется Subversion,скачать исходники можно так:
Код
svn co https://basin.svn.sourceforge.net/svnroot/basin basin
Эти темы возникли в результате моих вопросов по ходу написания:
Технический приём для формирования согласованных данных
Makefile: как с использованием gcc строить автоматические зависимости от .h файлов?
Вопрос по svn (Subversion)
Создание системы тестирования ПО.
Вопрос про разные реализации бэйсиков
[C/C++] Можно ли выразить порядковый номер элемента массива через индексы?
[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;
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
20.06.2009, 20:03     Пишем свой интерпретатор языка BASIC
Посмотрите здесь:
Пишем свой чекер C++
C++ пишем свой троян с нуля
Пишем свой класс, спецификатор доступа protected C++
C++ Интерпретатор небольшого языка программирования на С++
Не удается откомпилировать интерпретатор М-языка C++
Написать Интерпретатор Программного Языка(собственного) C++
Интерпретатор/компилятор ассемблер-подобного языка C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Evg
Эксперт CАвтор FAQ
17463 / 5701 / 361
Регистрация: 30.03.2009
Сообщений: 15,648
Записей в блоге: 26
23.12.2009, 21:52     Пишем свой интерпретатор языка BASIC #301
Кстати, давно хотел сказать, но всё время забывал. Тот тест, который ты у меня взял, он у тебя коряво работает.

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

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  
^Tecktonik_KiLLeR
1159 / 441 / 22
Регистрация: 23.06.2009
Сообщений: 6,230
Завершенные тесты: 1
23.12.2009, 22:33     Пишем свой интерпретатор языка BASIC #302
если что надо помогу с Хеллоу ворлд!
RazorQ
576 / 343 / 9
Регистрация: 06.02.2009
Сообщений: 1,386
26.12.2009, 17:57     Пишем свой интерпретатор языка BASIC #303
Я в голове прокручиваю мысли по поводу дебагера и не могу представить себе этот процесс даже в теории. В чем я уверен, так это в том, что не нужно изобретать велосипед, т.е. писать свой интерпретатор (я как минимум морально не готов писать). С другой стороны каким образом отслеживать ход программы во время интерпретации? Отдавать на съедение basin по строчке кода? А как быть с циклами и ветвлениями? Может есть какая-то поддержка со стороны самого интерпретатора? Так же я пока не знаю, откуда мне можно будет получить список переменных и как обновлять их значения.
#pragma
Временно недоступен
952 / 223 / 6
Регистрация: 12.04.2009
Сообщений: 921
26.12.2009, 18:22  [ТС]     Пишем свой интерпретатор языка BASIC #304
Я так думаю,что опираться мы будем на пользовательскую отладочную печать.Некое подобие уже реализовано в виде опций командной строки --trace-act,--trace-tree,--trace-silent,а также опций в самом коде с помощью инструкции OPTION. Проблема,я так понимаю,в остановке внутри самого интерпретатора по событию,зависящему от пользователя. Я вижу такое простое решение (хотя Evg наверняка его забракует) - в командную строку перед запуском интерпретатора подаются номера строк для остановки,а также имена нужных переменных для просмотра по какому-то согласованному формату.В этом случае интерпретатор будет останавливаться на этих строках в исходнике,параллельно печатая в stdout значения нужных переменных,и ожидая ввода пользователя (любую клавишу или enter).А уже IDE будет отлавливать эти значения,и показывать их,где нужно.

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

Ну это дебаггер встроенный,а как делать внешний,я пока не знаю
RazorQ
576 / 343 / 9
Регистрация: 06.02.2009
Сообщений: 1,386
26.12.2009, 18:39     Пишем свой интерпретатор языка BASIC #305
Хорошо. Всё же интерпретатор должен быть чистым (ИМХО), т.е. без встроенного отладчика. Но хотелось бы послушать, что скажет Evg, а я пока отложу написание дебагера.
Evg
Эксперт CАвтор FAQ
17463 / 5701 / 361
Регистрация: 30.03.2009
Сообщений: 15,648
Записей в блоге: 26
26.12.2009, 19:04     Пишем свой интерпретатор языка BASIC #306
В случае компилятора отладчик возможно делать внешним, потому как по результату работы компилятора генерится независимый (от компилятора) исполняемый файл. В этот файл складывается отладочная информация, по которой отладчик может найти соотвествие между кодом (данными) и текстом исходной программы.

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

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

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

Как вариант вместо stdout, stderr можно открывать дополнительные файловые потоки, опять-таки чтобы не путать печати программы с выводом интерпретатора
RazorQ
576 / 343 / 9
Регистрация: 06.02.2009
Сообщений: 1,386
27.12.2009, 16:17     Пишем свой интерпретатор языка BASIC #309
Слушайте, а как называется ваш язык программирования? Я не стал перечитывать всю тему, может вы уже говорили об этом. Просто я всегда называю его Basic (именно так, а не BASIC), может я ошибаюсь.
Evg
Эксперт CАвтор FAQ
17463 / 5701 / 361
Регистрация: 30.03.2009
Сообщений: 15,648
Записей в блоге: 26
27.12.2009, 18:03     Пишем свой интерпретатор языка BASIC #310
BASIC расшифровывается что-то типа "the Beginners All-sourpose Symbolic Instruction Code". Т.е. авторы взяли слово "basic" и сделали из него аббревиатуру. Поэтому провально писать все буквы заглавными. Диалектов бэйсика существует целая куча (грубо говоря, каждый разработчик делал немного по-своему). За основу мы брали Q-BASIC.
RazorQ
576 / 343 / 9
Регистрация: 06.02.2009
Сообщений: 1,386
27.12.2009, 18:36     Пишем свой интерпретатор языка BASIC #311
Выкладываю наработки. Версия не совсем в рабочем состоянии, но я уже выбился из сил искать ошибку! Прошу откомпилировать, запустить и выключить. А потом рассказать мне о впечатлениях.
Вложения
Тип файла: zip Basin-IDE.zip (109.8 Кб, 26 просмотров)
Evg
Эксперт CАвтор FAQ
17463 / 5701 / 361
Регистрация: 30.03.2009
Сообщений: 15,648
Записей в блоге: 26
27.12.2009, 20:57     Пишем свой интерпретатор языка BASIC #312
У меня пока отсутсвует линукс
#pragma
Временно недоступен
952 / 223 / 6
Регистрация: 12.04.2009
Сообщений: 921
28.12.2009, 07:05  [ТС]     Пишем свой интерпретатор языка BASIC #313
Почему-то у меня не скомпилировалось.
Листинг ошибок (после того,как выполнил qmake,а затем make)
Код
$ 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
RazorQ
576 / 343 / 9
Регистрация: 06.02.2009
Сообщений: 1,386
28.12.2009, 10:09     Пишем свой интерпретатор языка BASIC #314
Почему-то у меня не скомпилировалось.
Открываем mainwindow.ui в дизайнере -> выделяем кнопочку "Новый" или в списке действий выбираем newAct -> свойство priority устанавливаем по умолчанию (кнопочка похожая на Enter в свойствах)
#pragma
Временно недоступен
952 / 223 / 6
Регистрация: 12.04.2009
Сообщений: 921
28.12.2009, 14:50  [ТС]     Пишем свой интерпретатор языка BASIC #315
А можно как-то без дизайнера обойтись? Я просто хочу скомпилить проект в консоли.. Ты скажи,что в исходнике поменять,я поменяю,или патч сделай,а то я что-то не въеду с этими кнопочками.
RazorQ
576 / 343 / 9
Регистрация: 06.02.2009
Сообщений: 1,386
28.12.2009, 14:53     Пишем свой интерпретатор языка BASIC #316
#pragma, в таком случае просто удали строчку 88 из файла ui_mainwindow.h
RazorQ
576 / 343 / 9
Регистрация: 06.02.2009
Сообщений: 1,386
28.12.2009, 14:59     Пишем свой интерпретатор языка BASIC #317
Я тут на коленке подправил
Вложения
Тип файла: zip Basin-IDE.zip (113.0 Кб, 25 просмотров)
#pragma
Временно недоступен
952 / 223 / 6
Регистрация: 12.04.2009
Сообщений: 921
28.12.2009, 16:19  [ТС]     Пишем свой интерпретатор языка BASIC #318
Посмотрел.Вроде бы ничего,красиво.Почему-то LINE идёт курсивом.Может,возьмешь регекспы из моей версии? Там впринципе почти готово было (ну может пару слов зарезервированных не было). Когда показывается окно с ошибками,неплохо бы,чтобы оно было поменьше,а то немного великовато на фоне общего размера окна.Я в своей версии не смог его сделать узкого размера,но так,чтобы его можно было растягивать.Поэтому сделал просто узкий фиксированный размер.У нас ведь интерпретатор показывает только одну ошибку за раз,и столько места не нужно. Можно ещё сделать выделение строки с ошибкой другим цветом,чтобы подчеркнуть,что что-то не так.
Ну и если можно,сделать сохранение файла настроек для Basin-IDE в ту же папку,где лежит проект,и чтобы ничего не сохранялось в домашнюю папку,а то я заметил,сохраняется какой-то .conf файл: зачем?
У меня ещё такой вопрос есть: а для чего вообще эти ui файлы? Что они дают? Я без них как-то обходился,но в принципе и дизайнером не пользовался тоже.
RazorQ
576 / 343 / 9
Регистрация: 06.02.2009
Сообщений: 1,386
28.12.2009, 16:29     Пишем свой интерпретатор языка BASIC #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
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
28.12.2009, 16:47     Пишем свой интерпретатор языка BASIC
Еще ссылки по теме:
C++ Написать интерпретатор программного языка -помощь
C++ Интерпретатор музыки стандарта BASIC PLAY на С++
Задание: разработать "Интерпретатор языка". С чего начать? C++
C++ Перепишите пожалуйста код программы с языка Visual Basic в C++
По русскому названию языка программирования определить английское название этого языка C++

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

Или воспользуйтесь поиском по форуму:
#pragma
Временно недоступен
952 / 223 / 6
Регистрация: 12.04.2009
Сообщений: 921
28.12.2009, 16:47  [ТС]     Пишем свой интерпретатор языка BASIC #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);
Yandex
Объявления
28.12.2009, 16:47     Пишем свой интерпретатор языка BASIC
Закрытая тема Создать тему
Опции темы

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