Всем добрый день!
Получила такое сумбурное задание, помогите, пожалуйста, разобраться.
Необходимо реализовать парсер арифметического выражения на классах.
Проблема как раз в этих классах, т.е., как я поняла, они должны быть реализованы таким образом:
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;
Откуда взялись эти классы? Тебе что, задано их определение (без реализации), и тебе надо с их помощью реализовать парсер? Или у тебя есть задание, и ты думаешь, что классы TCustomToken/TNumberToken/TCustomTokens должны выглядеть именно так?
Слишком уж много непонятного в этих описаниях. Начнем с определения "парсер". Что делает этот парсер? Если переводит выражение в постфикс - это одно, тогда я еще как-то могу согласиться, что в TCustomTokens организован массив (имитирующий стек), который хранит только Char-ы, большего, чем хранение скобок и знаков арифм. операций от того стека не требуется... Но вот если придется еще и вычислять, то тут без стека, хранящего числа, никак не обойтись, следовательно чего-то в TCustomTokens уже не хватает...
Второе: чего это в TCustomToken есть метод LoadFromString (насколько я понимаю, читающий знак очередного оператора из входной строки с определенной позиции), а в TNumberToken такого метода нет? Что, числа не читаются с той же строки? Тогда откуда они берутся?
Третье: зачем присутствуют 3 разных не связанных друг с другом класса? Я понимаю, если бы TCustomToken и TNumberToken были наследниками какого-то базового класса, тогда можно было бы и стек сделать один, способный хранить и числа и знаки операций. Но у тебя вообще нет наследования.
Есть исходники еще одного парсера, он не выложен на моем сайте, который вычисляет выражения, содержащие +-*/^ и тригонометрические функции (включая обратные: arcsin/arccos/arctan), для FPC, но должно отработать и в Дельфи с небольшой корректировкой, если надо - скажи... Там, правда, тоже нет иерархии классов, все одним классом реализовано...
Да, задано именно такое определение классов.
Их надо было реализовать + в классах можно прописывать свои методы, свойства, поля(т.е. с ними можно делать что угодно, как я поняла, даже организовать наследование, надо только, чтобы основная структура сохранилась).
А три класса из-за того, что нас хотят научить работать с классами)
В условиях только не было прописано, что FItems: array [0..FCount-1] должен иметь тип char, это уже мои домыслы.
А так, по идее, должна быть первоначальная строка, в которую пользователь вводит выражение. Далее бежим по строке, если видим цифру, то её в TNumberToren, если знак, то в TCustomToken. Потом надо из двух классов, всё что получилось занести в третий класс. А далее посчитать выражение.
Была бы очень благодарна за ещё один парсер, тем более на классе)
Значит, смотри: используются вот такие классы:
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;
begin
result := X; Exit;
end;
Спасибо огромное!!!
Сейчас буду разбираться! Хотя задание и правда, мягко скажем, специфическое, на твоём сайте столько нормальных решений, а приходится что-то выдумывать(
Ещё раз спасибо!
p.s. я только, если что, ещё что-нибудь спрошу?))