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

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

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 1509, средняя оценка - 4.80
#pragma
Временно недоступен
 Аватар для #pragma
952 / 223 / 6
Регистрация: 12.04.2009
Сообщений: 921
20.06.2009, 20:03     Пишем свой интерпретатор языка BASIC #1
*****************
Благодаря форуму и 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)
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
26.10.2010, 17:55     Пишем свой интерпретатор языка BASIC #401
niXman, Конструктор/деструктор, аллокация/деаллокация.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
niXman
Эксперт C++
 Аватар для niXman
3133 / 1445 / 49
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
26.10.2010, 17:58     Пишем свой интерпретатор языка BASIC #402
Lavroff, возможно вы меня не правильно поняли.
как аллокатор должен себя вести по отношению к POD`ам? конструкторов/деструкторов ведь нет.
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
26.10.2010, 18:04     Пишем свой интерпретатор языка BASIC #403
niXman, К подам да. аллокация/деаллокация, инициализация только соответственно.
niXman
Эксперт C++
 Аватар для niXman
3133 / 1445 / 49
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
26.10.2010, 18:10     Пишем свой интерпретатор языка BASIC #404
как показывают эксперименты, к 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мя? он их передвинет в начало? перевыделит? или он удаляет с конца? по аллокатору ничего толкового не могу нагуглить..
#pragma
Временно недоступен
 Аватар для #pragma
952 / 223 / 6
Регистрация: 12.04.2009
Сообщений: 921
27.10.2010, 01:30  [ТС]     Пишем свой интерпретатор языка BASIC #405
Цитата Сообщение от 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,и просто ничего там не понял,вот бы поглядеть на хорошо написанную программу интерпретатора в самом простом варианте с функциями.
niXman
Эксперт C++
 Аватар для niXman
3133 / 1445 / 49
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
27.10.2010, 01:40     Пишем свой интерпретатор языка BASIC #406
Цитата Сообщение от #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/0ad678...b97eaaf36be157
#pragma
Временно недоступен
 Аватар для #pragma
952 / 223 / 6
Регистрация: 12.04.2009
Сообщений: 921
27.10.2010, 01:56  [ТС]     Пишем свой интерпретатор языка BASIC #407
Да,я это имел в виду
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16825 / 5246 / 321
Регистрация: 30.03.2009
Сообщений: 14,127
Записей в блоге: 26
27.10.2010, 13:10     Пишем свой интерпретатор языка BASIC #408
Цитата Сообщение от #pragma Посмотреть сообщение
Поэтому у меня есть пару предложений по этому поводу:
1) Оставить всё как есть,"законсервировать",и можно будет двигаться дальше,получив полезный опыт.
2) Переписать всё заново.
Я в общем-то не раз говорил, что нынешняя твоя реализация и идеи для построения вызовов приведут в тупик. Но объяснять это было бы слишком долго. Надо понять это изнутри. Теперь ты это понял. А потому это является очень ценным опытом. Ибо по себе знаю, что отрицательный опыт гораздо более полезен, чем положительный.

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

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

Цитата Сообщение от #pragma Посмотреть сообщение
Evg ,на самом деле я был бы непрочь взглянуть на твой вариант реализации с функциями (если он есть,конечно),а то я глядел на исходные коды gcc,и просто ничего там не понял,вот бы поглядеть на хорошо написанную программу интерпретатора в самом простом варианте с функциями.
Я не стал делать функции именно по той причине, что понимал масштаб геморроя. Потому я их и не делал Всё, что я сделал - это потому, что была неделя условно свободного времени перед отпуском и неделя условно свободного времени где-то внутри рабочего года. А больше я ничего и не делал с тех пор
niXman
Эксперт C++
 Аватар для niXman
3133 / 1445 / 49
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
27.10.2010, 19:29     Пишем свой интерпретатор языка BASIC #409
Цитата Сообщение от #pragma Посмотреть сообщение
Да,я это имел в виду
так мною предложенный вариант подходит?
#pragma
Временно недоступен
 Аватар для #pragma
952 / 223 / 6
Регистрация: 12.04.2009
Сообщений: 921
27.10.2010, 22:51  [ТС]     Пишем свой интерпретатор языка BASIC #410
Цитата Сообщение от Evg Посмотреть сообщение
Я предлагаю идти по второму пункту.
Заманчивое предложение,при условии наличия свободного времени. Пока что его маловато, и в перспективе не наблюдается
В-общем,я достаточно отчётливо уяснил важность планирования при написании программ,хотя бы намекающих на дальнейшее развитие. Как развить этот навык,я не знаю,ты говоришь,что это приходит с опытом,а может,это талант особый,-ну дальше видно будет.
В ближайшем будущем у меня будет немного времени,и я хотел бы посвятить его тому,чтобы дочитать Beej's Guide to Network Programming (возможно поэкспериментировать немного,ибо это очень интересная тема),немного про устройство Linux,и,может быть,дочитать уже наконец бедного Страуструпа. А то я чувствую,что в кодинге у меня даже некоторые привычки образоваться успели,а теория как была,так почти и осталась на том же уровне,когда я прекратил её изучать.
Цитата Сообщение от nixMan Посмотреть сообщение
так мною предложенный вариант подходит?
Да,это подходит,я даже наверное попытаюсь поменять,что нужно,чтобы хотя бы прога собиралась чисто,а то неохота так вот оставлять.
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16825 / 5246 / 321
Регистрация: 30.03.2009
Сообщений: 14,127
Записей в блоге: 26
27.10.2010, 23:09     Пишем свой интерпретатор языка BASIC #411
Цитата Сообщение от #pragma Посмотреть сообщение
В-общем,я достаточно отчётливо уяснил важность планирования при написании программ
Есть хорошее выражение: плохо спланированная работа требует в три раза больше времени, чем планировалось, а хорошо спланированная - только в два раза больше. С программами, в общем-то, то же самое. Как ты ни планируй, если идёт постоянное развитие, то всё равно что-то придётся переделывать
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
24.11.2011, 17:18     Пишем свой интерпретатор языка BASIC #412
Мне бы азы теории для совсем чайника. Хотя бы термины. Например, понятие "алфавит" совпадает с обыденным? А если нет, то что это такое? Можете дать для примера готовый алфавит, например, c++?
Nameless One
Эксперт С++
 Аватар для Nameless One
5753 / 3402 / 255
Регистрация: 08.02.2010
Сообщений: 7,393
24.11.2011, 20:35     Пишем свой интерпретатор языка BASIC #413
Алфавит в общем случае - это любое конечное множество символов. Т.е. для ЯП алфавит языка - это множество символов, которые могут в том или ином виде встречаться в исходнике (отдельный случай - это комментарии). Пример для С++
Теория (и практика) с самых азов: http://ru.wikipedia.org/wiki/Компиля..._и_инструменты
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
25.11.2011, 07:00     Пишем свой интерпретатор языка BASIC #414
Эйси. Теперь такой вопрос. Опередлил я алфавит, пытаюсь слепить свою кривоподелуху на тему компиляторов (первая пробу клавы приличным компилом точно не будет). Есть нечто, кторое должно стать кривокомпилятором, а потом может быть и компилятором, есть файл исходника. Решено отталкиваться от 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
}
. Ну и каким символом начинаются все? Или я чего то не так понял?
ValeryLaptev
Эксперт C++
1005 / 784 / 46
Регистрация: 30.04.2011
Сообщений: 1,595
25.11.2011, 14:30     Пишем свой интерпретатор языка BASIC #415
taras atavin, ну хоть немного же теорию надо читать!
Рекомендую 2 книги - простые и доступные:
Вирт: http://www.ozon.ru/context/detail/id/4803779/
Свердлов: http://www.ozon.ru/context/detail/id/3056680/
Nameless One
Эксперт С++
 Аватар для Nameless One
5753 / 3402 / 255
Регистрация: 08.02.2010
Сообщений: 7,393
25.11.2011, 15:13     Пишем свой интерпретатор языка BASIC #416
Цитата Сообщение от taras atavin Посмотреть сообщение
грамматика должна включать в себя начальный символ , или аксиому, с которой начинается получение любого предложения языка.
в терминологии контекстно-свободных грамматик существует четыре основных понятия:
  1. терминальные символы (токен) - элементарные символы языка, определяемые грамматикой
  2. нетерминалы (синтаксические переменные), описывающие множество строк терминалов способом, описываемым ниже
  3. продукции, состоящие из нетерминала (заголовок, левая часть продукции) стрелки и последовательности терминалов и/или нетерминалов (тело, правая часть продукции)
  4. один из нетерминальных символов, который указывается как стартовый (начальный)
для примера, если уж так хочется, можно рассмотреть С-подобный язык, который позволяет определять функции. Описание его грамматики может иметь такой вид (терминалы заключены в обратные кавычки, `E` - спец. терминал, который обозначает пустую строку символов, '|' - символ, с помощью которого группируются различные продукции для одного и того же нетерминала, с символа '#' начинается комментарий к самой грамматике):

Код
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
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16825 / 5246 / 321
Регистрация: 30.03.2009
Сообщений: 14,127
Записей в блоге: 26
25.11.2011, 15:26     Пишем свой интерпретатор языка BASIC #417
Nameless One,

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

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

Добавлено через 40 секунд
Или ты про "готовый алфавит"?
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16825 / 5246 / 321
Регистрация: 30.03.2009
Сообщений: 14,127
Записей в блоге: 26
25.11.2011, 16:36     Пишем свой интерпретатор языка BASIC #419
Если брать язык типа простого бэйсика, которий реализовал #pragma, то каждый statement начинается с ключевого слова. С точки зрения разбора это просто. Типа, если слово LET, то разбираем правило statement_let, если слово FOR, то разбираем правило statement_for. А в си это не совсем так. Поэтому он хочет понять, как с этим разбираться
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
25.11.2011, 16:44     Пишем свой интерпретатор языка BASIC
Еще ссылки по теме:

Пишем свой чекер C++
Не удается откомпилировать интерпретатор М-языка C++
Пишем свой класс, спецификатор доступа protected C++

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

Или воспользуйтесь поиском по форуму:
Nameless One
Эксперт С++
 Аватар для Nameless One
5753 / 3402 / 255
Регистрация: 08.02.2010
Сообщений: 7,393
25.11.2011, 16:44     Пишем свой интерпретатор языка BASIC #420
Цитата Сообщение от Evg Посмотреть сообщение
Если брать язык типа простого бэйсика, которий реализовал #pragma, то каждый statement начинается с ключевого слова. С точки зрения разбора это просто
с этим я соглашусь. А С++, в том виде, который мы имеем сейчас, очень плохо подходит в качестве языка, на основе которого нужно учиться писать компиляторы/интерпретаторы (ИМХО)
Yandex
Объявления
25.11.2011, 16:44     Пишем свой интерпретатор языка BASIC
Закрытая тема Создать тему
Опции темы

Текущее время: 19:58. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru