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

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

20.06.2009, 20:03. Показов 253942. Ответов 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
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
26.10.2010, 17:55
Студворк — интернет-сервис помощи студентам
niXman, Конструктор/деструктор, аллокация/деаллокация.
2
Эксперт С++
 Аватар для niXman
3211 / 1459 / 74
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
26.10.2010, 17:58
Lavroff, возможно вы меня не правильно поняли.
как аллокатор должен себя вести по отношению к POD`ам? конструкторов/деструкторов ведь нет.
2
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
26.10.2010, 18:04
niXman, К подам да. аллокация/деаллокация, инициализация только соответственно.
2
Эксперт С++
 Аватар для niXman
3211 / 1459 / 74
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
26.10.2010, 18:10
как показывают эксперименты, к POD`ам аллокатор применяется как указателю на тип при деаллокации. иначе никак.
C++
1
2
3
   std::string s;
   std::string::value_type* p = s.get_allocator().allocate(33);
   s.get_allocator().deallocate(p, 30);
вот только не понятно, после деаллокации 30ти байт, что станет с остальными 3мя? он их передвинет в начало? перевыделит? или он удаляет с конца? по аллокатору ничего толкового не могу нагуглить..
2
Временно недоступен
 Аватар для #pragma
957 / 228 / 14
Регистрация: 12.04.2009
Сообщений: 926
27.10.2010, 01:30  [ТС]
Цитата Сообщение от Evg Посмотреть сообщение
Бред какой-то. Это такое стандартное средство Си++ для работы с памятью чтоли?
Да не ,это просто функция,я её ещё давно сделал,чтобы хоть как-то контролировать память .Меня именно интересовал способ выделения/очистки вручную,так как хотелось посмотреть на значения переменных,напечатать их и т.д.
niXman, отдельное спасибо за предложение с шаблоном.
Цитата Сообщение от niXman Посмотреть сообщение
в данном случае, тип T не может иметь аргументов конструктора. это нормально?
Да,это может быть загвоздка. Я хотел переместить функцию memalloc в класс pool,и нужно именно несколько функций с параметрами,и одну без.. А разве так нельзя сделать?
пример
C++
1
2
3
4
5
6
template <typename T,typename A,typename B>
T *memalloc(A *a ,B *b) {
     allocated += sizeof(T);
     if (allocated > maxallocated) maxallocated = allocated;
     return new T(a,b);
}
?

Добавлено через 3 часа 0 минут
Evg,мне начинает казаться,что с добавлением функций программа зашла в тупик,ибо слишком много проблем всплывает на поверхность сейчас В их числе старый механизм провязки инструкций в список,который по уму надо полностью переделать,так как с добавлением SUB пришлось идти на ухищрения для связывания отдельных списков,и поэтому сейчас нельзя в начале программы писать определение функции. Так же нужно делать какой-то новый механизм добавления вызовов CALL,так как существующий опирается на уже существующие функции,то же самое с метками выхода из функции (RETURN),которые сделаны для связи листов инструкций. Я уже не говорю о работе с памятью,полного разделения run-time от построения дерева(которое тоже не до конца сделано), доработка тестовых печатей (сама система примитивна,и должна быть переделана) ... Я столько возился с этим кодом,что уже предвижу большой для меня объём работы (а времени не хватает).

Не по теме:

Весьма полезный опыт,хотя и долгий :) в итоге - планировать,планировать,планировать - а потом писать код.


Поэтому у меня есть пару предложений по этому поводу:
1) Оставить всё как есть,"законсервировать",и можно будет двигаться дальше,получив полезный опыт.
2) Переписать всё заново.
Evg ,на самом деле я был бы непрочь взглянуть на твой вариант реализации с функциями (если он есть,конечно),а то я глядел на исходные коды gcc,и просто ничего там не понял,вот бы поглядеть на хорошо написанную программу интерпретатора в самом простом варианте с функциями.
1
Эксперт С++
 Аватар для niXman
3211 / 1459 / 74
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
27.10.2010, 01:40
Цитата Сообщение от #pragma Посмотреть сообщение
Я хотел переместить функцию memalloc в класс pool,и нужно именно несколько функций с параметрами,и одну без.. А разве так нельзя сделать?
не очень понял вопроса..
ты об этом?:
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
#include <iostream>
#include <string>
 
template<typename T>
T* func() {
   return new T;
}
 
template<typename T, typename A1>
T* func(const A1& a1) {
   return new T(a1);
}
 
template<typename T, typename A1, typename A2>
T* func(const A1& a1, const A2& a2) {
   return new T(a1, a2);
}
 
int main() {
   std::string* s1 = func<std::string>();
   std::cout << "s1: " << *s1 << std::endl;
 
   std::string* s2 = func<std::string>("bla");
   std::cout << "s2: " << *s2 << std::endl;
 
   std::string* s3 = func<std::string>("blabla", 3);
   std::cout << "s3: " << *s3 << std::endl;
}
http://liveworkspace.org/code/... aaf36be157
3
Временно недоступен
 Аватар для #pragma
957 / 228 / 14
Регистрация: 12.04.2009
Сообщений: 926
27.10.2010, 01:56  [ТС]
Да,я это имел в виду
1
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
27.10.2010, 13:10
Цитата Сообщение от #pragma Посмотреть сообщение
Поэтому у меня есть пару предложений по этому поводу:
1) Оставить всё как есть,"законсервировать",и можно будет двигаться дальше,получив полезный опыт.
2) Переписать всё заново.
Я в общем-то не раз говорил, что нынешняя твоя реализация и идеи для построения вызовов приведут в тупик. Но объяснять это было бы слишком долго. Надо понять это изнутри. Теперь ты это понял. А потому это является очень ценным опытом. Ибо по себе знаю, что отрицательный опыт гораздо более полезен, чем положительный.

Я предлагаю идти по второму пункту. Потому что это тоже большой полезный опыт. Любая программа по мере своего развития рано или поздно сталкивается с тем, что нужно полностью переделывать отдельные компоненты или полностью менять архитектуру программы. Чем раньше ты научишься это делать, тем проще будет в будующем. К тому же такой опыт поможет тебе при написании программ изначально закладываться на будущую переделку и писать коды таким образом, чтобы они проще поддавались переделке.

Многие коммерческие фирмы идут по первому пункту. Практика показывает, что почти всегда это заканчивается закрытием проекта или банкротством

Цитата Сообщение от #pragma Посмотреть сообщение
Evg ,на самом деле я был бы непрочь взглянуть на твой вариант реализации с функциями (если он есть,конечно),а то я глядел на исходные коды gcc,и просто ничего там не понял,вот бы поглядеть на хорошо написанную программу интерпретатора в самом простом варианте с функциями.
Я не стал делать функции именно по той причине, что понимал масштаб геморроя. Потому я их и не делал Всё, что я сделал - это потому, что была неделя условно свободного времени перед отпуском и неделя условно свободного времени где-то внутри рабочего года. А больше я ничего и не делал с тех пор
2
Эксперт С++
 Аватар для niXman
3211 / 1459 / 74
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
27.10.2010, 19:29
Цитата Сообщение от #pragma Посмотреть сообщение
Да,я это имел в виду
так мною предложенный вариант подходит?
1
Временно недоступен
 Аватар для #pragma
957 / 228 / 14
Регистрация: 12.04.2009
Сообщений: 926
27.10.2010, 22:51  [ТС]
Цитата Сообщение от Evg Посмотреть сообщение
Я предлагаю идти по второму пункту.
Заманчивое предложение,при условии наличия свободного времени. Пока что его маловато, и в перспективе не наблюдается
В-общем,я достаточно отчётливо уяснил важность планирования при написании программ,хотя бы намекающих на дальнейшее развитие. Как развить этот навык,я не знаю,ты говоришь,что это приходит с опытом,а может,это талант особый,-ну дальше видно будет.
В ближайшем будущем у меня будет немного времени,и я хотел бы посвятить его тому,чтобы дочитать Beej's Guide to Network Programming (возможно поэкспериментировать немного,ибо это очень интересная тема),немного про устройство Linux,и,может быть,дочитать уже наконец бедного Страуструпа. А то я чувствую,что в кодинге у меня даже некоторые привычки образоваться успели,а теория как была,так почти и осталась на том же уровне,когда я прекратил её изучать.
Цитата Сообщение от nixMan Посмотреть сообщение
так мною предложенный вариант подходит?
Да,это подходит,я даже наверное попытаюсь поменять,что нужно,чтобы хотя бы прога собиралась чисто,а то неохота так вот оставлять.
1
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
27.10.2010, 23:09
Цитата Сообщение от #pragma Посмотреть сообщение
В-общем,я достаточно отчётливо уяснил важность планирования при написании программ
Есть хорошее выражение: плохо спланированная работа требует в три раза больше времени, чем планировалось, а хорошо спланированная - только в два раза больше. С программами, в общем-то, то же самое. Как ты ни планируй, если идёт постоянное развитие, то всё равно что-то придётся переделывать
3
 Аватар для taras atavin
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
24.11.2011, 17:18
Мне бы азы теории для совсем чайника. Хотя бы термины. Например, понятие "алфавит" совпадает с обыденным? А если нет, то что это такое? Можете дать для примера готовый алфавит, например, c++?
0
Эксперт С++
 Аватар для Nameless One
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
24.11.2011, 20:35
Алфавит в общем случае - это любое конечное множество символов. Т.е. для ЯП алфавит языка - это множество символов, которые могут в том или ином виде встречаться в исходнике (отдельный случай - это комментарии). Пример для С++
Теория (и практика) с самых азов: http://ru.wikipedia.org/wiki/К... нструменты
0
 Аватар для taras atavin
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
25.11.2011, 07:00
Эйси. Теперь такой вопрос. Опередлил я алфавит, пытаюсь слепить свою кривоподелуху на тему компиляторов (первая пробу клавы приличным компилом точно не будет). Есть нечто, кторое должно стать кривокомпилятором, а потом может быть и компилятором, есть файл исходника. Решено отталкиваться от c++, а в первом примере нет ничего что вышло бы за рамки c++. Есть функция, есть указатель на имя файла с исходником. Надо ли грузить его целиком в оперативу, или работать с диска? Ещё. Подводные камни байт-кода в роли внутреннего представления. Преимущества и недостатки шитого кода в роли целевого языка. Подводные камни обратной польской нотации в роли внутреннего представления арифметических, строковых, адресных и логических выражений. Строки будут поддерживать только конкатенацию, доуступ к символу и функции, но просто для единобезобразия с остальными выражениями.
грамматика должна включать в себя начальный символ , или аксиому, с которой начинается получение любого предложения языка.
То есть? Что то я не знаю ни одного языка, на которых бы каждое предложение начиналось с фиксированного символа, или последовательности таких символов. Вот взять, например, c++.
C++
1
2
3
4
5
6
7
8
9
int main ()
{
 int f;
 int a;
 int r;
 f=2;
 a=4; r=f+a;
 return r;
}
Пердолжения - это, судя по всему,
C++
1
int main()
,
C++
1
{
,
C++
1
int f;
,
C++
1
int a;
C++
1
int r;
C++
1
f=2;
C++
1
a=4;
C++
1
r=f+a;
C++
1
return r;
,
C++
1
}
. Ну и каким символом начинаются все? Или я чего то не так понял?
0
Эксперт С++
1069 / 848 / 60
Регистрация: 30.04.2011
Сообщений: 1,659
25.11.2011, 14:30
taras atavin, ну хоть немного же теорию надо читать!
Рекомендую 2 книги - простые и доступные:
Вирт: http://www.ozon.ru/context/detail/id/4803779/
Свердлов: http://www.ozon.ru/context/detail/id/3056680/
0
Эксперт С++
 Аватар для Nameless One
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
25.11.2011, 15:13
Цитата Сообщение от taras atavin Посмотреть сообщение
грамматика должна включать в себя начальный символ , или аксиому, с которой начинается получение любого предложения языка.
в терминологии контекстно-свободных грамматик существует четыре основных понятия:
  1. терминальные символы (токен) - элементарные символы языка, определяемые грамматикой
  2. нетерминалы (синтаксические переменные), описывающие множество строк терминалов способом, описываемым ниже
  3. продукции, состоящие из нетерминала (заголовок, левая часть продукции) стрелки и последовательности терминалов и/или нетерминалов (тело, правая часть продукции)
  4. один из нетерминальных символов, который указывается как стартовый (начальный)
для примера, если уж так хочется, можно рассмотреть С-подобный язык, который позволяет определять функции. Описание его грамматики может иметь такой вид (терминалы заключены в обратные кавычки, `E` - спец. терминал, который обозначает пустую строку символов, '|' - символ, с помощью которого группируются различные продукции для одного и того же нетерминала, с символа '#' начинается комментарий к самой грамматике):

Code
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
program -> definitions # программа - эта серия определений (функций)
 
definitions -> definition definitions # серия определений - это одно определение,
                                      # за кот. следует серия определений
             | `E`                    # либо пустая строка
 
definition -> prototype body # определение состоит из прототипа функции и ее тела
 
# прототип функции состоит из спецификатора типа
# возвращаемого значения, идентификатора функции,
# терминального символа `(`, списка параметров,
# терминального символа `)`
prototype -> typespec funid `(` paramlist `)` 
 
# список параметров состоит либо из пустой строки,
# либо из описания одного параметра, за которым следует
# терминал `,` и список параметров
paramlist -> `E` | param `,` paramlist
 
# описание параметра состоит из спецификатора типа #
# и идентификатора переменной-параметра
param -> typespec varid
 
# тело функции состоит из (возможно пустого) списка утверждений,
# заключенный в терминалы `{` и `}`
body -> `{` statements `}`
 
statements -> `E` | statement statements
 
# и так далее описываются остальные нетерминалы
Цитата Сообщение от taras atavin Посмотреть сообщение
Ну и каким символом начинаются все? Или я чего то не так понял?
а начинается все с нетерминала program
1
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
25.11.2011, 15:26
Nameless One,

> # и так далее описываются остальные нетерминалы

Я так понимаю, что именно это "и так далее" в первую очередь интересовало Тараса (т.е. именно про это он изначально и спросил)
1
Эксперт С++
 Аватар для Nameless One
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
25.11.2011, 15:50
Evg, так он же спросил про стартовый нетерминал, нет?
Цитата Сообщение от taras atavin Посмотреть сообщение
То есть? Что то я не знаю ни одного языка, на которых бы каждое предложение начиналось с фиксированного символа, или последовательности таких символов. Вот взять, например, c++.
Цитата Сообщение от taras atavin Посмотреть сообщение
Ну и каким символом начинаются все? Или я чего то не так понял?
А если его интересует "и так далее", то пусть гуглит по запросу "c++ formal grammar"

Добавлено через 40 секунд
Или ты про "готовый алфавит"?
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
25.11.2011, 16:36
Если брать язык типа простого бэйсика, которий реализовал #pragma, то каждый statement начинается с ключевого слова. С точки зрения разбора это просто. Типа, если слово LET, то разбираем правило statement_let, если слово FOR, то разбираем правило statement_for. А в си это не совсем так. Поэтому он хочет понять, как с этим разбираться
0
Эксперт С++
 Аватар для Nameless One
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
25.11.2011, 16:44
Цитата Сообщение от Evg Посмотреть сообщение
Если брать язык типа простого бэйсика, которий реализовал #pragma, то каждый statement начинается с ключевого слова. С точки зрения разбора это просто
с этим я соглашусь. А С++, в том виде, который мы имеем сейчас, очень плохо подходит в качестве языка, на основе которого нужно учиться писать компиляторы/интерпретаторы (ИМХО)
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
25.11.2011, 16:44
Помогаю со студенческими работами здесь

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

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
420
Закрытая тема Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru