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

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

Восстановить пароль Регистрация
Другие темы раздела
C++ Меню и список http://www.cyberforum.ru/cpp-beginners/thread41194.html
Здравствуйте форумчане. Помоги пожалуйста в следующем вопросе: У меня есть 2связный список, написано меню. Но в моменте когда написано make a list и delete custom необходимо чтобы выводились: Введите элемент и номер. вот сам код: #ifndef __list_h #define __list_h #include <iostream>
C++ Здравствуйте! Не могу поместить class в один файл с программой. file.hpp #include "Cat.hpp" // здесь классы "2)" Cat::Cat(int initialAge) { itsAge = initialAge; } Cat::~Cat() { http://www.cyberforum.ru/cpp-beginners/thread41186.html
Массивы строк C++
Привет всем! Задан массив строк. Как узнать который символ встечаетса найбольшое количество раз в етом массиве?
C++ вывод на экран набор треугольников и квадратов, которые произвольно двигаются и меняют размер
Please, help me!!! Вот текст программы, которая выводит на экран набор треугольников и квадратов, которые произвольно двигаются и меняют размер только квадратов. Проблема в том, что необходимо исправить код, чтоб фигуры не исчезали за экран (т.е. 640х460) и были компактным набором, т.е. двигались неменяя своего положения относительно друг друга и стукаясь об стенку экрана меняли свое...
C++ Округление дробного числа до целого в большую сторону. http://www.cyberforum.ru/cpp-beginners/thread41139.html
Доброго дня. Я новичок в программирование на Visual C++. Проблема такая программа должна считать кол-во месяцев, если числа целые то программа шла дальше, если дробное то (например 3.33333) программа не округляет это число (в большую сторону) до 4. Перелопатил тонны литературы, но пропустил или не нашёл этого, большая просьба написать функцию которая могла бы это делать, или способ какой.
C++ Код из Delphi в C++ Нужно написать курсовую на C++. Сам я в программировании плохо шарю (не программист). Попросил у народу помощи, помогли. Но решение на Delphi: {$APPTYPE CONSOLE} type byteset=set of byte; var d:array of longint; procedure c; var a,b,i:longint; подробнее

Показать сообщение отдельно
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16828 / 5249 / 321
Регистрация: 30.03.2009
Сообщений: 14,132
Записей в блоге: 26
02.07.2009, 11:04     Пишем свой интерпретатор языка BASIC
Отсмотрю попозже или вечером. Вкратце пока то, что с ходу могу ответить

Чтобы не пуатть терминологию, не слудует называть деяние "дебаггером". Более правильно - "внутренние отладочные печати" или "внутренняя отладка", чтобы не путать с программой-отладчиком (которая и есть "дебаггер")

Удобнее для разных фич делать внутреннюю отладку под разными макросами. Т.е. парсер печатать под одним макросом, таблицу переменных под другим и т.п. Когда программа разрастётся, то суммарная выдача станет очень большой, а потому надо уже делить мух от котлет

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

> // Что и каким образом передаётся в функцию?

В функцию не должно передаваться ничего. Смысл следующий. Ты вызываешь parser_GetToken, которая в процессе работы взводит 4 глобальных переменных. А процедура parser_PrintCurToken просто печатает эти 4 значения. Т.е. пара этих процедур работает симметрично: одна записывает результат, другая его читает и печатает

> если ещё не надоел

Попробую пояснить попроще. Как-то меня начальник спросил, считаю ли я себя хорошим специалистом. Я ответил что нет, потому как считаю, что без того, чтобы кого-то обучать (обучить) хорошим специалистом никогда не станешь. Заниматься преподаванием мне как-то неинтересно, ибо обучшение материала строго по плану и по расписанию - это попросут затратить кучу усилий практически впустую. В твоём же случае немного по другому. Ты сам в этом процессе заинтересован, пинать тебя не надо. Программирование - работа творческая, она не может идти по расписанию. Когда ты хочешь - ты программируешь. И программируешь то, что интересно, а не то, что записано в плане. Когда есть желание и заинтересованность - то производительность работы очень высокая. Поэтому я считаю, что всё (или почти всё), что я тебе рассказываю - оно оказывается с пользой для дела. Поэтому в том числе и в моих интересах, чтобы ты довёл эту работу до какого-то логически завершённого состояния.

Добавлено через 51 минуту 10 секунд
Ну будещее. Выкладывай исходники в двух экземплярах:
1. Так, как ты уже делаешь (чтобы с форума просто посомтреть можно было)
2. Заархивируй весь каталог с исходниками (чтобы к себе по простуму скопировать и запустить)

Добавлено через 2 минуты 4 секунды
Да, вот ещё. Посмотри ещё у меня в исходниках судоку как сделано ASSERT. Это внутренние самопроверки. Для порядку тоже учись этой вещью пользоваться. Если непонятно, что это - поясню

Добавлено через 5 минут 49 секунд
Ну и сразу концептуальное замечание. В debugger_Print у тебя стоит switch. В таких случаях надо обязательно лепить ветку default, в которой помещать вызов FatalError (ну или как там её назвать). В один прекрасный расстановка таких условий в недостижимых точках и ASSERT'ы сэкономят тебе кучу времени при отладке

Добавлено через 14 минут 23 секунды
Ну и ещё момент. У тебя отладочная печать принудительно срётся в файл. Здесь бы по аналогии с разделением флага DEBUG сделал разделение выходного файла. Т.е. завёл бы глобалы "ofstream debug_FileParser, debug_FileVarTable", сделал бы процедуру инициализации debug_Init, в котором бы делал открытие данных файлов. А дальше уже по ситуации. Если тебе удобно раздельная печать - открываешь два разных файла. Если тебе удобно видеть их совместно (когда надо понять, что в каком порядке запускается), то один файл открываешь, а для второго делаешь типа "debug_FileVarTable = debug_FileParser". Если нужно печатаь на экран, а не в файл, то просто "debug_FileParser = cout; debug_FileVarTable = cout;". В итоге получается, что у тебя всё гибко, а менять код надо только в одной процедуре

Кстати, выше я писал, что в parser_PrintCurToken не надо ничего подавать (я обычно исхожу из того, что печать всегда идёт на экран). В данном случае ты поступил абсоютно правильно, подав сюда указатель на файл (правда назвал его неправильно и имя параметра у тебя перекрывает имя глобальной переменной). Процедура печати должна только печатать. А куда печатать - это пускай разбираются "наверху" и подают файл параметром.

Содержимое печати (т.е. то, что ты увидишь) удобнее было бы не тупо 4 значения (при этом надо помнить, что на какой позиции находится), а что-то типа следующего. Для строки "LET a=51"

file="source.bsc", line=1, token=KW_LET, token_str="LET"
file="source.bsc", line=1, token=IDENT, token_str="a"
file="source.bsc", line=1, token=DELIM_EQUAL, token_str="="
file="source.bsc", line=1, token=CONST_INT, token_str="51"

Кстати, при правильном построении синтаксического разборщика TokenNext, который ты добавил, он не нужен. По крайней мере в теории пока выглядит так

Добавлено через 38 секунд
Нумерацию строк принято начинать с 1, а не с 0

Добавлено через 21 минуту 25 секунд
Посмотрел твой вариант GetToken - моск сразу же сломался

Ещё раз формальное описание грамматики (чтобы перед глазами было)

Код
Const = ConstInt | ConstFloat
ConstInt = Digit { Digit }
ConstFloat = Digit { Digit } "." Digit { Digit }
Ident = Letter { Letter | Digit }
Letter = "A" | "B" | ... | "y" | "z"
Digit = "0" | "1" | ... | "9"
KeywordLet = "LET"
KeywordPRINT = "PRINT"
Правильное построение примерно такое:

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
// Пропускаем все пробелы и знаки табуляции
 
// Если текущий символ - латинская буква, значит это начало ключевого слова
// или идентификатора. Если текущий символ - цифра,значит это
// начало константы. В остальных случаях это хз что
if (isalpha(...))
{
  // Читаем из потока до тех пор, пока имеем букву или цифру,
  // таким образом формируем целое слово. После чело проверяем,
  // это является ли слово ключевым. Если да, то это keyword,
  // иначе идетификатор
  while (...) { ... }
} else if (isdigit(...))
{
  // Для простоты пока читаем до тех пор, пока умеем цифру или точку
  // Опять получаем слово. Если оно содержит точку, значит плавающая
  // константа, иначе целочисленная
  // Но потом код надо будет аккуратно передалать, чтобы "1.1.1" не воспринималось
  // как единый токен.
  while (...) { ... }
} else
{
  // Разбираем delimiter'ы. Выбирай для себя способы, которыми задаются
  // комментарии, пропустить их тоже можно будет здесь (после чего сделать
  // goto на начало разбора). В скриптовых языках принято, что комментарий
  // начинается символом '#' и заканчивается в конце строки
}
 
Текущее время: 10:57. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru