Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Другие темы раздела
C++ Меню и список Здравствуйте форумчане. Помоги пожалуйста в следующем вопросе: У меня есть 2связный список, написано меню. Но в моменте когда написано make a list и delete custom необходимо чтобы выводились:... https://www.cyberforum.ru/ cpp-beginners/ thread41194.html C++ Здравствуйте! Не могу поместить class в один файл с программой. file.hpp
#include "Cat.hpp" // здесь классы "2)" Cat::Cat(int initialAge) { itsAge = initialAge; } Cat::~Cat() {
C++ Массивы строк https://www.cyberforum.ru/ cpp-beginners/ thread41179.html
Привет всем! Задан массив строк. Как узнать который символ встечаетса найбольшое количество раз в етом массиве?
C++ вывод на экран набор треугольников и квадратов, которые произвольно двигаются и меняют размер Please, help me!!! Вот текст программы, которая выводит на экран набор треугольников и квадратов, которые произвольно двигаются и меняют размер только квадратов. Проблема в том, что необходимо... https://www.cyberforum.ru/ cpp-beginners/ thread41152.html
Округление дробного числа до целого в большую сторону. C++
Доброго дня. Я новичок в программирование на Visual C++. Проблема такая программа должна считать кол-во месяцев, если числа целые то программа шла дальше, если дробное то (например 3.33333) ...
C++ Код из Delphi в C++ https://www.cyberforum.ru/ cpp-beginners/ thread41137.html
Нужно написать курсовую на C++. Сам я в программировании плохо шарю (не программист). Попросил у народу помощи, помогли. Но решение на Delphi: {$APPTYPE CONSOLE} type byteset=set of byte; ...
C++ массив структур и функции https://www.cyberforum.ru/ cpp-beginners/ thread41103.html
Разработать модель прайс-листов по комплектующим. Каждую единицу оборудования должна описывать соответствующая структура (например, структура, описывающая видеокарты или мониторы), объект которой...
C++ Таймер не работает в Turbo C++
Реализовал таймер в Visual C++. #include "stdafx.h" #include <iostream.h> #include <conio.h> #include <time.h> #include <stdio.h> #include <stdlib.h> const int N=100000000;
C++ не могу завершить код :( https://www.cyberforum.ru/ cpp-beginners/ thread41093.html
он меняет 1 слово из фаила example.txt затем создоёт vasea-out.txt с уже изменёным текстом.. но он меняет только 1 слово.. как сделать чтобы он менял болише слов к приемру в example.txt написано...
C++ MS VC++ 6.0:Как "подавить" выдачу конкретных варнингов в конкретных местах? Не хочу, чтобы выдавались конкретные варнинги, относящиеся к определённым областям заданных файлов. Как это сделать. Про "Warning Level" в насторйках студии я в курсе. Но мне нужно подавить... https://www.cyberforum.ru/ cpp-beginners/ thread41092.html
Последний метод итераций C++
Здравсвуйте программисты! Спасибо за ответы на предыдущие посты. Осталось решить методом итераций систему уравнений. Вчера Сазари мне подсказал как делать методом Зейделя, осталось методом итераций....
C++ не переводит из string в char* помогите пожалуйста задание: операции со строками с использованием шаблона string #include <algorithm> #include <iostream> #include <string> #include <conio.h> using namespace std; https://www.cyberforum.ru/ cpp-beginners/ thread41080.html
Evg
Эксперт CАвтор FAQ
21245 / 8261 / 636
Регистрация: 30.03.2009
Сообщений: 22,606
Записей в блоге: 30
30.06.2009, 12:23 0

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

30.06.2009, 12:23. Показов 238176. Ответов 464
Метки (Все метки)

Лучший ответ Сообщение было отмечено Памирыч как решение

Решение

Точка не должна отлавливаться. У тебя "10.0" должно идти как единая грамматическая единица (token). Собственно, потому я и предложил навести порядок, что логически у тебя некорректно написано.

Сейчас у тебя get_token выдирает число по одной циферке. Это не есть правильно. get_token за раз должен выдрать целиком грамматическую единицу. Т.е. если записано "123", то за раз будет выдрано "123", если "123.45", то "123.45". А вот если "123.45.67", то первая лексическая единица будет "123.45", а следующая "." (или ".67", если понимать дополнительный вариант записи плавающих чисел). Если это ключевое слово "print", то и будет "print" (с чем у тебя на текущий момент проблемы). Сейчас у меня под рукой нет формальных описаний, но если желаешь - ознакомлю тебя с формальными описаниями грамматики и лексики

Добавлено через 1 минуту 40 секунд
> Я уже успел поискать про машинную запись чисел с плавающей точкой,я так
> понимаю,этот ньюанс требует пересмотра посимвольного разбора с помощью
> putback?

Нет. Как я уже писал, get_token за раз должен выдрать "123.45", котору затем стандартными функциями ты превратишь в плавающее число. Возможно, я пока объясняю слишком непонятно, но если ты морально готов к перелопачиванию своей программы, могу начать пояснять более подробно.

Добавлено через 5 минут 0 секунд
Хотя нашёл в инете пример формального описания грамматики. Так что если надо - могу вкратце пояснить суть работы грамматического анализатора

Добавлено через 2 часа 51 минуту 6 секунд
============================== ============================== ====

В общем, появилось немного свободного времени на работе. Так что родил примерно следующее пояснение

Есть две вещи разного уровня: грамматика и лексика. Грамматика - это по сути дела правила построения слов из отдельных букв. Лексика - построение предложений из слов (а последние построены по правилам грамматики)

Давай рассмотрим простейший вариант того, какие грамматические единицы (token'ы) должны поддерживаться нашим интерпретатором:
  • константы (числа): целочисленные и плавающие
  • идентификаторы (имена переменных)
  • ключевые слова: в нашем случае пока только PRINT, но для простоты в будущем развитии я бы ввёл ещё LET
  • знаки операций, которые принято называть разделителями (delimiter) : + - * / | & ~ =
  • признак конца строки (поскольку конец строки будет являться разделителем между предложениями)
  • признак конца файла

Задача парсера, который по сути дела является грамматическим анализатором, является нарезка входного текста на слова (token'ы). При этом грамматический анализатор будет пропускать комментарии, ненужные пробелы и знаки табуляции. Мы будем считать, что один вызов GetToken (я всё-таки обзову именно так, чтобы не путать с тем, что сейчас есть у тебя) вынимает из входного потока одно слово (token). Как это будет представлено на уровне данных, пока не рассматриваем (чисто чтобы теорию понять)

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

Код
let a = 5.123 # комментарий
print a
последовательные вызовы GetToken должны вернуть следующий набор значений:
  • Ключевое слово (keyword) LET
  • Идентификатор (identifier) A
  • Операция (delimiter) =
  • Плавающая константа (float constant) 5.123
  • EOL (конец строки)
  • Ключевое слово PRINT
  • Идентификатор A
  • EOL (конец строки)
  • EOF (конец файла)

При этом комментарии за пределы парсера вообще не вылезают. Дабы остальным компонентам с ними не возиться

Теперь, как это всё должно выглядеть технически. По результату вызова GetToken фактически должен возвращать в качестве результата некие два значения. Первым значением является непосредственное строковое представление слова, которое полезно для печати диагностики, отладки, а так же необходимо для разбора идентификаторов и констант. Т.е. для нашего примера этими строковыми значениями будут "LET", "A", "=", "5.123" и т.д. Вторым значением является значение некоего enum'а, которое удобно обрабатывать в виде целочисленного значения и которое является описанием того, что у нас записано в строке. Таким образом пара этих значений полностью описывает наш token

Как конкретно сделать enum - зависит от того, как тебе удобно работать.
Я бы сделал так:

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
enum parser_TokenType
{
  TOKEN_NULL = 0,
 
  TOKEN_CONST_INT,   // целочисленная константа
  TOKEN_CONST_FLOAT, // плавающая константа
 
  TOKEN_IDENT,       // идентификатор
 
  TOKEN_KW_LET,      // ключевое слово LET
  TOKEN_KW_PRINT,    // ключевое слово PRINT
 
  TOKEN_DELIM_EQUAL, // знак "="
  TOKEN_DELIM_PLUS,  // знак "+"
  TOKEN_DELIM_MINUS, // знак "-"
  ....
 
  TOKEN_EOL,         // конец строки
  TOKEN_EOF,         // конец файла
 
  TOKEN_LAST
};
При этом для значений TOKEN_CONST_INT, TOKEN_CONST_FLOAT и TOKEN_IDENT нам необходимо второе значение (которое описывает строковое представление token'а), а в остальных случаях элемент enum'а полностью описывает наш token

В итоге интерфейс нашего грамматического анализатора будет примерно таким:

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/* Инициализация парсера. В качестве file_name подаём имя файла,
 * с которым работаем. В случае проблем с открытием файла возвращаем
 * false, если всё в порядке - true */
extern bool parser_Init (const char *file_name);
 
/* Процедура parser_GetToken вынимает очередное слово из нашего входного
 * потока. Порезультату работы записываются переменные parser_CurToken
 * и parser_LastTokenStr. Процедура parser_GetToken возвращает то же значение,
 * что записывается в parser_CurToken (для удобства работы).
 * В перменные parser_CurFile, parser_CurLine записывается информация
 * о положении в файле текущего token'а (для выдачи ошибок) */
extern parser_TokenType parser_GetToken (void);
extern parser_TokenType parser_CurToken;
extern char *parser_CurTokenStr;
extern char *parser_CurFile;
extern unsigned parser_CurLine;
 
/* Отладочная печать текущего token'а */
extern void parser_PrintCurToken (void);
 
/* Завершение работы */
extern void parser_Finish (void);
Попробуй наваять парсер (который по сути является грамматическим анализатором) примерно по такому интерфейсу. Либо меняй его на своё усмотрение, лишь бы остался принцип того, что на один вызов GetToken вытаскивается грамматическая единица целиком. И заодно встрой в программу под макросом или опцией отладочную печать из-под своего парсера. Тут тоже можешь экспериментировать. Печать может быть интегрирована прямо вовнутрь GetToken'а, можно её вызывать снаружи. Лишь бы тебе было удобно по печатям отслеживать процесс работы

Ну и весь грамматический анализатор полезно выделить в отдельный файл

Добавлено через 14 минут 34 секунды
Вот примерное формальное описание грамматики:

Код
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"
То, что написано с заглавной буквы, представляет собой правило. То, что в кавычках - непосредственно указанные внутри кавычек символ(ы). Символ | означает один из вариантов, то, что заключено в фигурные скобки - это ноль или более потворений того, что заключено в них (скобках)

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

Самая первая задача - научиться нарезать на слова в случае, когда нет грамматических ошибок. А уже потом пытаться отсекать ошибочные случаи

Вернуться к обсуждению:
Пишем свой интерпретатор языка BASIC C++
6
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
30.06.2009, 12:23
Готовые ответы и решения:

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

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

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

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

464
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
30.06.2009, 12:23
Помогаю со студенческими работами здесь

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

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

Не удается откомпилировать интерпретатор М-языка
Задача: взять интерпретатор М-языка на сайте...

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

Написать интерпретатор программного языка -помощь
Здраствуйте! Ребят, кто хорошо разбирается в C++ помогите пожалуйста с реализацией данного задания...

Интерпретатор/компилятор ассемблер-подобного языка
Привет! Чую, что изобрёл велисипед, даже скорее велопарк, но всё же, поделюсь: Некоторое время...

0
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2022, CyberForum.ru