我查看了一下代码,原来的处理方式是考虑到 class 关键字有以下几种应用形式:
TMyClass = class; // 用来预先申明类
TMyClass = class(TObject, IUnknown); // 仅声明一个子类
TMyClass = class(TObject, IUnknown) // 跟上一种相同
end;
TMyClass = class(TObject, IUnknown) // 完整的声明
FValue: Integer;
public
...
end;
在您列出的代码中:
if (Lex.TokenPos < CurrPos) and (Lex.TokenID = tkSemiColon) then
Result.PosKind := pkType
这一句用来处理第一种情况。
else if (Lex.TokenPos < CurrPos) and (Lex.TokenID = tkRoundOpen) then
begin
while (Lex.TokenPos < CurrPos) and not (Lex.TokenID in
[tkNull, tkRoundClose]) do
DoNext;
if (Lex.TokenPos < CurrPos) and (Lex.TokenID = tkRoundClose) then
begin
DoNext(True);
if (Lex.TokenPos < CurrPos) and (Lex.TokenID = tkSemiColon) then
Result.PosKind := pkType;
end;
end
用来跳过类声明中括号部分的内容,如果找到 ) 后发现接着是一个 ; 号,说明是第二种情况,结束类处理。
否则:
if Result.PosKind = pkClass then
InClass := True;
标识当前在类定义中,恢复循环,直到遇见一个 end; 为止,用于处理后面的两种情况。
您增加的代码,如果去掉也是可以工作的,因为执行完 InClass := True 后,继续循环,如果紧接着是 end; 的话,会执行:
tkEnd:
begin
if InClass then
begin
Result.PosKind := pkType;
InClass := False;
end
这个单元用在输入助手中,感觉功能还很欠缺,有时间我会写个更完善的语法分析单元。
|