IPB
ЛогинПароль:

> Прочтите прежде чем задавать вопрос!

1. Заголовок темы должен быть информативным. В противном случае тема удаляется ...
2. Все тексты программ должны помещаться в теги [code=pas] ... [/code], либо быть опубликованы на нашем PasteBin в режиме вечного хранения.
3. Прежде чем задавать вопрос, см. "FAQ", если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно такую задачу уже решали!
4. Не предлагайте свои решения на других языках, кроме Паскаля (исключение - только с согласия модератора).
5. НЕ используйте форум для личного общения, все что не относится к обсуждению темы - на PM!
6. Одна тема - один вопрос (задача)
7. Проверяйте программы перед тем, как разместить их на форуме!!!
8. Спрашивайте и отвечайте четко и по существу!!!

 
 Ответить  Открыть новую тему 
> Парсер на классах
сообщение
Сообщение #1


Пионер
**

Группа: Пользователи
Сообщений: 78
Пол: Женский

Репутация: -  0  +


Всем добрый день!
Получила такое сумбурное задание, помогите, пожалуйста, разобраться.
Необходимо реализовать парсер арифметического выражения на классах.
Проблема как раз в этих классах, т.е., как я поняла, они должны быть реализованы таким образом:
type
TCustomToken=class //здесь должны храниться только литералы исходного выражения
private
FText: string;
public
property Text: string read fText; //должно быть св-ом
procedure LoadFromString(const S, Pos): Integer;
end;
TNumberToken=class //только цифры исходного выражения
private
FValue: Integer; //должно быть св-ом
public
property Value: Integer read FValue;
end;
TCustomTokens=class //всё выражение (должно считываться из двух предыдущих классов)
private
FCount: Integer; //должно быть св-ом
FItems: array [0..FCount-1] of Char; //должно быть св-ом
function GetSymbol(Index: Integer): ;
procedure SetSymbol(Index: Integer; Value: Longint);
public
property Count: Integer read FCount;
property Items[index: Integer]: Longint read GetCoord write SetCoord; //не уверена, что правильно оформила
end;


на форуме нашла такой код парсера
Постфиксная форма записи
http://volvo71.narod.ru/faq_folder/postfix.htm
там есть и ооп, но
подскажите, пожалуйста, как можно парсер оформить в виде именно этих классов. Как я поняла, каждый класс должен выступать в виде стека, и как правильно распорядиться свойствами классов?
Заранее большое спасибоsmile.gif)!
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #2


Гость






Откуда взялись эти классы? Тебе что, задано их определение (без реализации), и тебе надо с их помощью реализовать парсер? Или у тебя есть задание, и ты думаешь, что классы TCustomToken/TNumberToken/TCustomTokens должны выглядеть именно так?

Слишком уж много непонятного в этих описаниях. Начнем с определения "парсер". Что делает этот парсер? Если переводит выражение в постфикс - это одно, тогда я еще как-то могу согласиться, что в TCustomTokens организован массив (имитирующий стек), который хранит только Char-ы, большего, чем хранение скобок и знаков арифм. операций от того стека не требуется... Но вот если придется еще и вычислять, то тут без стека, хранящего числа, никак не обойтись, следовательно чего-то в TCustomTokens уже не хватает...

Второе: чего это в TCustomToken есть метод LoadFromString (насколько я понимаю, читающий знак очередного оператора из входной строки с определенной позиции), а в TNumberToken такого метода нет? Что, числа не читаются с той же строки? Тогда откуда они берутся?

Третье: зачем присутствуют 3 разных не связанных друг с другом класса? Я понимаю, если бы TCustomToken и TNumberToken были наследниками какого-то базового класса, тогда можно было бы и стек сделать один, способный хранить и числа и знаки операций. Но у тебя вообще нет наследования.

Есть исходники еще одного парсера, он не выложен на моем сайте, который вычисляет выражения, содержащие +-*/^ и тригонометрические функции (включая обратные: arcsin/arccos/arctan), для FPC, но должно отработать и в Дельфи с небольшой корректировкой, если надо - скажи... Там, правда, тоже нет иерархии классов, все одним классом реализовано...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #3


Пионер
**

Группа: Пользователи
Сообщений: 78
Пол: Женский

Репутация: -  0  +


Да, задано именно такое определение классов.
Их надо было реализовать + в классах можно прописывать свои методы, свойства, поля(т.е. с ними можно делать что угодно, как я поняла, даже организовать наследование, надо только, чтобы основная структура сохранилась).
А три класса из-за того, что нас хотят научить работать с классамиsmile.gif)

В условиях только не было прописано, что FItems: array [0..FCount-1] должен иметь тип char, это уже мои домыслы.

А так, по идее, должна быть первоначальная строка, в которую пользователь вводит выражение. Далее бежим по строке, если видим цифру, то её в TNumberToren, если знак, то в TCustomToken. Потом надо из двух классов, всё что получилось занести в третий класс. А далее посчитать выражение.

Была бы очень благодарна за ещё один парсер, тем более на классеsmile.gif)
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #4


Гость






Значит, смотри: используются вот такие классы:

  Tok_Type = (_UNDEF, _NUMBER, _OPERATOR, _END);
TokenString = string[16];

tbase = class
tokType: Tok_Type;
constructor create;
end;
topertoken = class(tbase)
private
FValue: char;
public
constructor loadfromstring(const s: string; var p: integer);
constructor stop;
property Value: char read FValue write FValue;
end;
tnumbertoken = class(tbase)
private
FValue: double;
public
constructor loadfromstring(const s: string; var p: integer);
property Value: double read FValue write FValue;
end;


tcalc = object
function proceed(): double;
constructor create(lpszCommand: string);
destructor destroy(); virtual;

private
TokenValue: tbase;

procedure SetFunction(lpszCommand: string);
procedure GetToken(); virtual;
function mul_div(): double;

protected
pCurrPos: integer;
_Function: string;

function add_sub(): double;
function prim(): double; virtual;
end;
Предупреждаю сразу о нескольких вещах:
1) это работает только с арифметическими операциями/скобками/вещественными числами
2) все классы, кроме TCalc были прикручены в программу по принципу "чтобы было, потому что есть в задании", изначально в парсере использовалось только 2 класса, TCalc и TVarCalc (один для вычисления выражений без переменных, второй - для вычислений с участием переменных, второй класс в прикрепленную программу не вошел, из первого было вычищено все, что касается функций)
3) такую программу лично я никогда бы не принял. Еще раз: написано это - только для того, чтобы показать, насколько это бредово получается. Без этих "классов-довесков" программа выглядит намного стройнее и красивее;
4) на некоторых версиях Дельфи (до 2009) потребуется заменить конструкцию Exit(X) на
begin
result := X; Exit;
end;


Прикрепленные файлы
Прикрепленный файл  parser.pas ( 5.69 килобайт ) Кол-во скачиваний: 296
 К началу страницы 
+ Ответить 
сообщение
Сообщение #5


Пионер
**

Группа: Пользователи
Сообщений: 78
Пол: Женский

Репутация: -  0  +


Спасибо огромное!!!
Сейчас буду разбираться! Хотя задание и правда, мягко скажем, специфическое, на твоём сайте столько нормальных решений, а приходится что-то выдумыватьsad.gif(
Ещё раз спасибо!
p.s. я только, если что, ещё что-нибудь спрошу?))

Сообщение отредактировано: Triplet -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 





- Текстовая версия 28.03.2024 16:26
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name