![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Что такое идентификатор по правилам Object Pascal?
Antonn © (2005-08-27 12:12:00)Наткнулся на задание лабораторной работы:
"Дан текст, выяснить, является ли этот текст идентификатором (по правилам Object Pascal)."
Может это и глупо, но не знаю я, что относится к идентификатору, соответственно зание не могу выполнить. Подскажите, что это?
Antonn (2005-08-28 12:03:00) [1]Anatoly Podgoretsky © (28.08.05 10:51) [32]
уже поздно, иду на 5 курс. Да и Дельфи тут изучают для ознакомления, всего семестр(а результат уже виден:)).
Anatoly Podgoretsky (2005-08-28 10:51:00) [2]Смени институт, ничему хорошему там тебя не научат.
Antonn (2005-08-28 04:53:00) [3]GuAV © (28.08.05 1:20) [30]
Можно записать в ресурс и грузить TStrings.LoadFromStream
ну не можно, говорю же. меня за использование процедур(в смысле, когда не в TButtonOnClick код) гоняют... Это так вообще идиотизм, имхо.
GuAV (2005-08-28 01:20:00) [4]
> В моем задании все должно содержаться в программе,
> без дополнительных внешних файлов.
Можно записать в ресурс и грузить TStrings.LoadFromStream
Anatoly Podgoretsky (2005-08-27 19:56:00) [5]И скорость
Lst.IndexOf(UpperCase(Slovo)) <> -1;
и разделение данных и логики.
А также независимость. Можно использовать для разных языков с близкими правилами или разных версий одного языка. Данные не обязательно должны быть в файле.
Antonn (2005-08-27 18:39:00) [6]Anatoly Podgoretsky © (27.08.05 18:15) [27]
Пропущено ценное предложение [19], решающее и документирование правил и быстродействие и расширяемость без переделки программы.
это при условии, что нужна расширяемость без переделки. В моем задании все должно содержаться в программе, без дополнительных внешних файлов.
Anatoly Podgoretsky (2005-08-27 18:15:00) [7]Пропущено ценное предложение [19], решающее и документирование правил и быстродействие и расширяемость без переделки программы.
Anatoly Podgoretsky (2005-08-27 18:13:00) [8]Если говорить об оптимальности, то обе плохии, но об оптимальности вопрос не стоял.
Главное чтобы правильно работало.
Даже в последнем варианте до оптимальности далеко.
Одно только
if not(s[1] in ['a'..'z','A'..'Z','_']) then exit;
перенесеное на строку выше даст большой прирост.
и цикл не с 1 а с 2 тоже даст прирост.
Но не будете же вы мериться оптимальностью?
Antonn (2005-08-27 17:26:00) [9]begin...end © (27.08.05 17:19) [24]
Не учтён случай пустой строки s.
угу, не делал, потому что в задании дается "непустая последовательность символов"
begin...end (2005-08-27 17:19:00) [10]> Antonn © (27.08.05 17:11) [22]
> у меня быстрее
Я не ставил своей целью написать наиболее быструю функцию, решающую данную задачу. Своё решение я не навязываю. Хотите -- пользуйтесь, хотите -- нет.
> Antonn © (27.08.05 17:15) [23]
Не учтён случай пустой строки s.
Antonn (2005-08-27 17:15:00) [11]begin...end © (27.08.05 16:58) [21]
я, кстати, сделал так:
function Reserved(s:string):boolean; из [18]
function GetSlovoIdentifier(s:string):boolean;
var i:integer;
begin
result:=false;
if not(Reserved(s)) then begin
if not(s[1] in ['a'..'z','A'..'Z','_']) then exit;
for i:=1 to length(s) do
if not(s[i] in ['a'..'z','A'..'Z','_','0'..'9']) then exit;
result:=true;
end;
end;
Antonn (2005-08-27 17:11:00) [12]Джо © (27.08.05 16:41) [19]
Это потенциальный глюкогенератор, а ну функция :)
попрошу указать, где это она глючная:)
И почему метод в [19] лучше.
begin...end © (27.08.05 16:58) [21]
попробывал только для опреления резервированых(через QueryPerformanceCounter) - у меня быстрее:)
begin...end (2005-08-27 16:58:00) [13]> Antonn © (27.08.05 16:33) [18]
Для Delphi 7 я бы использовал примерно такой код:
uses StrUtils;
function IsValidIdentifier(const Text: string): Boolean;
const
ValidSymbols = ['a'..'z', 'A'..'Z', '0'..'9', '_'];
FirstSymbols = ValidSymbols - ['0'..'9'];
ReservedWords: array [1..65] of string =
('and', 'array', 'as', 'asm',
'begin',
'case', 'class', 'const', 'constructor',
'destructor', 'dispinterface', 'div', 'do', 'downto',
'else', 'end', 'except', 'exports',
'file', 'finalization', 'finally', 'for', 'function',
'goto',
'if', 'implementation', 'in', 'inherited', 'initialization', 'inline', 'interface', 'is',
'label', 'library',
'mod',
'nil', 'not',
'object', 'of', 'or', 'out',
'packed', 'procedure', 'program', 'property',
'raise', 'record', 'repeat', 'resourcestring',
'set', 'shl', 'shr', 'string',
'then', 'threadvar', 'to', 'try', 'type',
'unit', 'until', 'uses',
'var',
'while', 'with',
'xor');
var
I, L: Integer;
begin
L := Length(Text);
// 1. Text не должен быть пустым, и его первый символ должен входить во множество FirstSymbols
Result := (L > 0) and (Text[1] in FirstSymbols);
// 2. Все символы Text, стоящие после первого, должны входить во множество ValidSymbols
I := 2;
while (I <= L) and Result do
begin
Result := Text[I] in ValidSymbols;
Inc(I)
end;
// 3. Text не должен находиться среди строк ReservedWords
Result := Result and (AnsiIndexText(Text, ReservedWords) = -1)
end.
Однако следует обратить внимание на то, что некоторые слова могут считаться зарезервированными лишь при определённых обстоятельствах (об этом тоже написано в справке). Например, слово private является зарезервированным в контексте описания класса. Это, в частности, означает, что обычную переменную с именем private объявить можно, а поле класса с таким именем -- нет. Поэтому нужно решить, как быть в этом случае, и, возможно, подкорректировать массив ReservedWords.
Джо (2005-08-27 16:43:00) [14]Кроме того, обрати внимание на [17] Anatoly Podgoretsky © в плане того, что не забудь предоставить преподавателю текстовый файл с этим самым списком. Ибо reserved words зависят от версии компилятора.
Джо (2005-08-27 16:41:00) [15]
> [18] Antonn © (27.08.05 16:33)
Это потенциальный глюкогенератор, а ну функция :)
Для отсечения зарезервированных слов можно сделать совсем просто. Создай текстовый файл со списком этих слов, каждое слово на новой строке, все символы в ВЕРХНЕМ РЕГИСТРЕ. Затем создаешь экземпляр TStringList. Загружаешь в него файл - Lst.LoadFromFile(...). Проверка на зарезервированное слово выглядит в таком случае просто до безобразия:
Reserved := Lst.IndexOf(UpperCase(Slovo)) <> -1;
И всё :)
Antonn (2005-08-27 16:33:00) [16]Anatoly Podgoretsky © (27.08.05 16:15) [17]
посмотреть эти правила. Посмотрев их
негде смотреть, только Ф1 в Delphi, а там по англицки, а учитывая
> Сбило с толку то, что в условии задается не одно слово
> (там для 10 заданий давался один текст), а предложение.
и
> в английском не силен, тем более что нужно принциально
> точно перевести и понять.
потому и сюда обратился.
> Одно из правил гласит - только одно слово в
> идентификаторе
это я знал, но в условии давалось предложение, вот у меня в возникло AV:)
В общем, пусть сам преподаватель разбирается, как с предложением быть, я сделал для одного слова.
begin...end © (27.08.05 16:14) [16]
Я бы использовал константный массив и функцию AnsiIndexText из модуля StrUtils.
может покажусь наглым, но можно пример?
я вот такую конструкцию собрал:
function Reserved(s:string):boolean;
var _b:boolean;
begin
if pos('['+lowercase(s)+']','[div][dispinterface][destructor][constructor]'
+'[class][asm][as][array][or][label][else][div][implementation]'
+'[interface][const][and][downto][not][in][uses][begin][end][end]'
+'[case][of][if][procedure][function][var][then][asm][for][to][do]'
+'[while][until][string]')> 0 then _b:=true else _b:=false;
if not(_b) then
if pos('['+lowercase(s)+']','[string][set][shl][shr][resourcestring][raise]'
+'[record][repeat][property][program][packed][out][library][mod][is]'
+'[inline][nil][interface][initialization][object][inherited]'
+'[implementation][except][exports][file][finalization][finally]'
+'[goto]')> 0 then _b:=true else _b:=false;
if not(_b) then
if pos('['+lowercase(s)+']','[xor][with][until][unit][type][try][threadvar]')> 0
then _b:=true else _b:=false;
result:=_b;
end;
Anatoly Podgoretsky (2005-08-27 16:15:00) [17]Antonn © (27.08.05 16:06) [15]
Правильно понял и в задании явно было сказано (по правилам Object Pascal)- это ключевая фраза, по ней ты должен был посмотреть эти правила. Посмотрев их у тебя не осталось бы вопросов, поскольку они сформулированы однозначно.
Одно из правил гласит - только одно слово в идентификаторе
Стандартная функция есть, она зашита в дебрях компилятора и наружу не выдается, да и пользы от нее мало, поскольку правила меняются от версии к версии. Это кроме того означает, что при решении задания ты должен опубликовать правила. Иначе возможно несогласование представлений о идентификаторах между тобой и предподователем.
begin...end (2005-08-27 16:14:00) [18]> Antonn © (27.08.05 16:06) [15]
> Кстати, есть ли стандартная функция, позволяющая узнать, является ли слово зарезервированым?
Нет.
> я пока обхожусь if и pos
Я бы использовал константный массив и функцию AnsiIndexText из модуля StrUtils.
Antonn (2005-08-27 16:06:00) [19]Anatoly Podgoretsky © (27.08.05 15:48) [14]
> Прочитав внимательно и понял 0,
я понял, что без понимания "идентификатор" далеко не уеду. И так ясно, что надо сравнивать, не понятны были условия, налагаемые "идентификатором". Сбило с толку то, что в условии задается не одно слово (там для 10 заданий давался один текст), а предложение.
Кстати, есть ли стандартная функция, позволяющая узнать, является ли слово зарезервированым? я пока обхожусь if и pos, но вдруг опять велосипедом пользуюсь...
Anatoly Podgoretsky (2005-08-27 15:48:00) [20]Это уже философия, но главное в 0, а в 1 только спецификация и к тому же это просто вырезка из стандартной справки. Прочитав внимательно и понял 0, можно дальше смотреть спецификацию в оригинале.
Сама задача подчеркиваю элементарная. Один цикла и серия IF и особого интереса не представляет. Вся сложность в понимании задания, что от тебя хочет предподователь. Недеюсь, что речь не идет о работодателе.