Написать программу, использующую механизм управления при помощи таблиц (управление осуществляется данными!). Нужно выделить следующие типы лексем: Целое число со знаком Вещественное число со знаком Скобка
Ориентировочная схема работы главного цикла программы: 1. Ввод символа из файла 2. Переход автомата в новое состояние в зависимости от введенного символа и текущего состояния 3. Вывод символа в выходной файл, либо другое действие (в зависимости от задания)
Перевод автомата в новое состояние (п. 2) и выбор действия для выполнения (п. 3) могут быть реализованы несколькими способами. От способа реализации зависит максимальный балл за выполнение работы: 1. Выбор действия и состояния с помощью ветвлений (if, switch) – 60% 2. Выбор состояния с помощью таблицы (массива), а действия с помощью ветвления – 80% 3. Выбор состояния и действия с помощью таблиц (для действий используются указатели на функции) – 100%
Чуть позже узнал, что есть очень важные ограничения на реализацию: программа может запоминать только текущее состояние и последний введенный символ. Не должны использоваться никакие дополнительные массивы или переменные для хранения введенных данных.
После ограничений пришлось удалить весь код и набросать этот: http://pastebin.ru/NlYjOVPg
Помогите разобраться, как мне полностью выделить лексему, например, несколько 123 - как целое со знаком, а не по отдельности, как 1 - целое со знаком, 2 - целое со знаком, 3 - целое со знаком.
@T2skler, IMHO плодотворной идеей будет сделать для каждого состояния свою таблицу переходов. Причем, ячейка таблицы представляет собой два поля: действие (указатель на функцию) и новое состояние (указатель на соответствующую таблицу).
И для полноты картины введите еще один символ -- EOF.
Тогда достаточно следующих состояний:
Start
Sign
Int
Real
и действия:
ERR
ERR_AND_BRACKET
BRACKET
INT
INT_AND_BRACKET
REAL
INT_AND_BRACKET
NONE
Например, знак в состоянии Start вызывает NONE и переход к Sign, цифра в Sign вызывает NONE и переход в Int, знак в Int вызывает INT и переход в Sign, ... знак в Sign вызывает ERR и переход опять в Sign и т.п.
Теперь о загадочных XXX_AND_BRACKET.
Очевидно, что скобка в Start вызывает BRACKET и переход в Start.
Скобка в Sign с одной стороны должна вызвать ошибку, а с другой -- это ведь просто лексема скобка. Поэтому вызовем ERR_AND_BRACKET, которая сначала вызовет ERR и затем BRACKET, а потом сразу перейдем в Start.
Похожим образом обработаем скобку в состояниях Int и Real. Только вместо ERR вызываем INT или REAL.
EOF в любом состоянии завершает программу (вероятно в состоянии Sign нужно вызвать ERR(?) или добавить действия XXX_AND_EOF, аналогичные XXX_AND_BRACKET)
Наверняка что-то упустил, но Вы уж сами додумайте... Попробуйте, думаю у Вас все получится.
Я года три назад писал небольшой скриптовой язык и интересовался вопросом. Как выше написал @VladD, не стоит изобретать велосипед. Проще всего воспользоваться Flex. Ему задаешь определенные правила, а на выходе он генерирует C'шный код, который уже легко встраиваешь под задачу.
Это сэкономит тебе кучу времени, а в итоге получешь отличный код.
P.S. Если не ошибаюсь он умеет и в C++.
Если кол-во состояний конечно и можно запоминать только номер текущего состояния и последний введённый символ, то узнать что мы прочитали 123, а не 213 нельзя. В противном случае кол-во состояний было бы пропорционально вводу или сам ввод (или позиции в нём) необходимо отдельно хранить.
Зная только состояние внутри конечного автомата и текущий символ, можно определить было ли прочитано целое, действительное числа или скобка.
Например, ragel позволяет создать конечный автомат из регулярного выражения:
%%{
machine number_fsm;
integer = ('+' | '-')? digit+;
float = ('+' | '-')? (digit+ ('.' digit*)? | '.' digit+)
(('e' | 'E') ('+' | '-')? digit+)?;
paren = '(' | ')';
token = integer | float | paren;
main := token**;
}%%
. Чтобы получить эту картинку, необходимо сохранить вышеприведённый код в number_fsm.rl
файл и выполнить команды:
$ ragel -F1 -p -V -o number_fsm.dot number_fsm.rl
$ dot -Tpng -o number_fsm.png number_fsm.dot
$ display number_fsm.png
ragel также умеет генерировать таблицы перехода для состояний и исполнять действия в любом месте на выбранном языке (например, С, Go).
Не стройте велосипед, воспользуйтесь lex
/flex
.
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Есть приложение на QT C++ для AndroidСтоит задача развернуть приложение на весь экран
Пишу на С++Задача в состоит в том, чтобы посчитать значения функции,используя генератор случайных чисел
У меня старая ОС(windows xp) и компилятор(mvs 2010) на данный момент доступны только две технологии писать свои форточки winforms и голый winapi, какую технологию...
Стоит задача получить страницу с сайта, войдя по ip, при этом указать HOST и путь страницыРеализация нужна для Qt 5+ (так уж настроена сеть)