No longer needed

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@492 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
inoussa 2008-06-26 15:12:37 +00:00
parent a2c31b16a1
commit 79abba7d4b
2 changed files with 0 additions and 3124 deletions

View File

@ -1,487 +0,0 @@
{
This unit is part of the Web Service Toolkit
Copyright (c) 2006 by Inoussa OUEDRAOGO
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
}
unit ws_parser;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils,
parserdefs;
Type
EParserException = class(Exception)
End;
{ TPascalParser }
TPascalParser = class
private
FStream : TStream;
FTokenizer : TParser;
FErrorMessage : String;
FSymbolTable : TSymbolTable;
FCurrentSymbol : TAbstractSymbolDefinition;
private
Property Tokenizer : TParser Read FTokenizer;
procedure SetErrorMessage(Const AValue : String);
procedure CheckCurrentString(Const AString : String);
private
procedure BeginParsing();
procedure EndParsing();
function GetSourceLine: Integer;
function ReadUntil(Const AText : String; Const ARaiseException : Boolean):Boolean;
procedure SkipComment();
function NextToken(): Char;
Private
procedure ParseHeader();
procedure ParseInterfaceSection();
procedure ParseUses();
procedure ParseTypeDeclaration();
procedure ParseInterfaceType(Const AName : String);
procedure ParseEnumType(Const AName : String);
procedure ParseClassType(Const AName : String);
public
constructor Create(AStream : TStream; ASymbolTable : TSymbolTable);
destructor Destroy();override;
procedure Error(Const AMsg : String);overload;
procedure Error(Const AMsg : String; Const AArgs : Array of const);overload;
function Parse():Boolean;
property SourceLine: Integer read GetSourceLine;
property ErrorMessage : String read FErrorMessage;
property SymbolTable : TSymbolTable Read FSymbolTable;
End;
implementation
Type
TPascalToken = (
ptNone,
ptUnit, ptInterface, ptUses, ptType,
ptImplementation, ptEnd,
ptProcedure, ptFunction,
ptSemicolon, ptComma, ptPeriod, ptEqual, ptColon,
ptLeftParenthesis, ptRigthParenthesis,
ptLeftSquareBracket, ptRigthSquareBracket,
ptConst, ptVar, ptOut,
ptClass
);
Const
PascalTokenStrMAP : Array[TPascalToken] Of String = (
'',
'UNIT', 'INTERFACE', 'USES', 'TYPE',
'IMPLEMENTATION', 'END',
'PROCEDURE', 'FUNCTION',
';', ',', '.', '=', ':',
'(', ')',
'[', ']',
'CONST', 'VAR', 'OUT',
'CLASS'
);
function GetPascalTokenStr(Const AToken:TPascalToken):String;
begin
Result := PascalTokenStrMAP[AToken];
end;
function GetPascalTokenFromStr(Const ATokenStr:String):TPascalToken;
begin
Result := Succ(ptNone);
For Result := Result To High(TPascalToken) Do Begin
If AnsiSameText(ATokenStr,PascalTokenStrMAP[Result]) Then
Exit;
End;
Result := ptNone;
end;
{ TPascalParser }
procedure TPascalParser.SetErrorMessage(const AValue: String);
begin
FErrorMessage := AValue;
end;
procedure TPascalParser.Error(const AMsg: String);
begin
Raise EParserException.Create(AMsg);
end;
procedure TPascalParser.Error(const AMsg: String; const AArgs: array of const);
begin
Raise EParserException.CreateFmt(AMsg,AArgs);
end;
procedure TPascalParser.CheckCurrentString(const AString: String);
begin
If Not AnsiSameText(Tokenizer.TokenString,AString) Then
Error('"%s" expected.',[AString]);
end;
procedure TPascalParser.BeginParsing();
begin
end;
procedure TPascalParser.EndParsing();
begin
end;
function TPascalParser.GetSourceLine: Integer;
begin
Result := Tokenizer.SourceLine;
end;
function TPascalParser.ReadUntil(Const AText : String; Const ARaiseException : Boolean):Boolean;
begin
While ( Tokenizer.Token <> toEOF ) And ( Not AnsiSameText(Tokenizer.TokenString,AText) ) Do
Tokenizer.NextToken();
Result := AnsiSameText(Tokenizer.TokenString,AText);
If ARaiseException And ( Not Result ) Then
Error('"%s" not found.',[AText]);
end;
procedure TPascalParser.SkipComment();
const L_C = '{'; R_C = '}';
begin
While ( FTokenizer.TokenString = L_C ) do begin
ReadUntil(R_C,False);
FTokenizer.NextToken();
end;
end;
function TPascalParser.NextToken(): Char;
begin
SkipComment();
Result := FTokenizer.NextToken();
SkipComment();
end;
procedure TPascalParser.ParseHeader();
begin // Unit UnitName;
SkipComment();
Tokenizer.CheckTokenSymbol(GetPascalTokenStr(ptUnit));
NextToken();
Tokenizer.CheckToken(toSymbol);
FSymbolTable.Name := Tokenizer.TokenString;
NextToken();
CheckCurrentString(GetPascalTokenStr(ptSemicolon));
NextToken();
end;
procedure TPascalParser.ParseInterfaceSection();
begin
ReadUntil(GetPascalTokenStr(ptInterface),True);
Tokenizer.CheckTokenSymbol(GetPascalTokenStr(ptInterface));
NextToken();
Tokenizer.CheckToken(toSymbol);
If Tokenizer.TokenSymbolIs(GetPascalTokenStr(ptUses)) Then
ParseUses();
ReadUntil(GetPascalTokenStr(ptType),True);
Tokenizer.CheckToken(toSymbol);
If Tokenizer.TokenSymbolIs(GetPascalTokenStr(ptType)) Then Begin
NextToken();
Repeat
ParseTypeDeclaration();
Until ( Tokenizer.Token = toEOF ) Or
Tokenizer.TokenSymbolIs(GetPascalTokenStr(ptImplementation)) Or
Tokenizer.TokenSymbolIs(GetPascalTokenStr(ptProcedure)) Or
Tokenizer.TokenSymbolIs(GetPascalTokenStr(ptFunction));
End;
end;
procedure TPascalParser.ParseUses();
begin
Tokenizer.CheckTokenSymbol(GetPascalTokenStr(ptUses));
NextToken();
Repeat
Tokenizer.CheckToken(toSymbol); //UnitName
NextToken();
If AnsiSameText(Tokenizer.TokenString,GetPascalTokenStr(ptSemicolon)) Then
Break;
CheckCurrentString(GetPascalTokenStr(ptComma));
NextToken();
Until ( Tokenizer.Token = toEOF ) Or AnsiSameText(Tokenizer.TokenString,GetPascalTokenStr(ptSemicolon));
CheckCurrentString(GetPascalTokenStr(ptSemicolon));
NextToken();
end;
procedure TPascalParser.ParseTypeDeclaration();
var
sname : string;
begin
Tokenizer.CheckToken(toSymbol);
sname := Tokenizer.TokenString;
NextToken();
CheckCurrentString(GetPascalTokenStr(ptEqual));
NextToken();
if AnsiSameText(Tokenizer.TokenString,GetPascalTokenStr(ptLeftParenthesis)) then
self.ParseEnumType(sname)
else if AnsiSameText(Tokenizer.TokenString,GetPascalTokenStr(ptClass)) then
self.ParseClassType(sname)
else begin
Tokenizer.CheckToken(toSymbol);
if Tokenizer.TokenSymbolIs(GetPascalTokenStr(ptInterface)) then
ParseInterfaceType(sname)
else begin
ReadUntil(GetPascalTokenStr(ptEnd),True);
NextToken();// End
NextToken();// ;
end;
end;
end;
procedure TPascalParser.ParseInterfaceType(const AName: String);
Var
sbl : TInterfaceDefinition;
procedure ReadIntfHeader();
begin
NextToken();
Repeat
Tokenizer.CheckToken(toSymbol);
NextToken();
If AnsiSameText(Tokenizer.TokenString,GetPascalTokenStr(ptRigthParenthesis)) Then Begin
NextToken();
Break;
End;
NextToken();
CheckCurrentString(GetPascalTokenStr(ptComma));
NextToken();
Until ( Tokenizer.Token = toEOF ) ;
end;
procedure ReadProcedure(Const AProc : Boolean);
Var
tmpStr,prmName : String;
tmpTkn : TPascalToken;
pr : TMethodDefinition;
prmM : TParameterModifier;
dataTypeSbl : TTypeDefinition;
foundSymbol : TAbstractSymbolDefinition;
begin
NextToken();
Tokenizer.CheckToken(toSymbol);
tmpStr := Tokenizer.TokenString;
If AProc Then
pr := sbl.AddMethod(tmpStr,mtProcedure)
Else
pr := sbl.AddMethod(tmpStr,mtFunction);
NextToken();
If AnsiSameText(Tokenizer.TokenString,GetPascalTokenStr(ptLeftParenthesis)) Then Begin
NextToken();
If AnsiSameText(Tokenizer.TokenString,GetPascalTokenStr(ptRigthParenthesis)) Then
NextToken()
Else Begin
Repeat
Tokenizer.CheckToken(toSymbol);
tmpStr := Tokenizer.TokenString;
tmpTkn := GetPascalTokenFromStr(tmpStr);
prmM := pmNone;
If ( tmpTkn = ptConst ) Then Begin
prmM := pmConst;
End Else If ( tmpTkn = ptVar ) Then Begin
prmM := pmVar;
End Else If ( tmpTkn = ptOut ) Then Begin
prmM := pmOut;
End;
If ( prmM > pmNone ) Then Begin
NextToken();
tmpStr := Tokenizer.TokenString;
End;
prmName := tmpStr;
NextToken();
CheckCurrentString(GetPascalTokenStr(ptColon));
NextToken();
Tokenizer.CheckToken(toSymbol);
tmpStr := Tokenizer.TokenString;
foundSymbol := FSymbolTable.Find(tmpStr);
If Assigned(foundSymbol) And ( Not foundSymbol.InheritsFrom(TTypeDefinition) ) Then
Error('Type symbol expected where "%s" was found.',[foundSymbol.Name]);
If Assigned(foundSymbol) Then
dataTypeSbl := foundSymbol As TTypeDefinition
Else Begin
dataTypeSbl := TTypeDefinition.Create(tmpStr);
FSymbolTable.Add(dataTypeSbl);
End;
pr.AddParameter(prmName,prmM,dataTypeSbl);
NextToken();
tmpStr := Tokenizer.TokenString;
If AnsiSameText(Tokenizer.TokenString,GetPascalTokenStr(ptRigthParenthesis)) Then Begin
NextToken();
Break;
End;
NextToken();
Until ( Tokenizer.Token = toEOF ) ;
End;
End;
If Not AProc Then Begin
CheckCurrentString(GetPascalTokenStr(ptColon));
NextToken();
Tokenizer.CheckToken(toSymbol);
tmpStr := Tokenizer.TokenString;
dataTypeSbl := FSymbolTable.Find(tmpStr) As TTypeDefinition;
If Not Assigned(dataTypeSbl) Then Begin
dataTypeSbl := TTypeDefinition.Create(tmpStr);
FSymbolTable.Add(dataTypeSbl);
End;
pr.AddParameter('result',pmOut,dataTypeSbl);
NextToken();
End;
CheckCurrentString(GetPascalTokenStr(ptSemicolon));
NextToken();
end;
procedure ReadFunction();
begin
ReadProcedure(False);
end;
procedure ReadGUID();
begin //['{804A3825-ADA5-4499-87BF-CF5491BFD674}']
CheckCurrentString(GetPascalTokenStr(ptLeftSquareBracket));
NextToken();
FTokenizer.CheckToken(toString);
sbl.InterfaceGUID := FTokenizer.TokenString;
NextToken();
CheckCurrentString(GetPascalTokenStr(ptRigthSquareBracket));
NextToken();
end;
begin
Tokenizer.CheckTokenSymbol(GetPascalTokenStr(ptInterface));
sbl := TInterfaceDefinition.Create(AName);
FSymbolTable.Add(sbl);
FCurrentSymbol := sbl;
NextToken();
if AnsiSameText(Tokenizer.TokenString,GetPascalTokenStr(ptLeftParenthesis)) then
ReadIntfHeader();
if AnsiSameText(Tokenizer.TokenString,GetPascalTokenStr(ptLeftSquareBracket)) then
ReadGUID();
repeat
if Tokenizer.TokenSymbolIs(GetPascalTokenStr(ptProcedure)) then
ReadProcedure(True)
else if Tokenizer.TokenSymbolIs(GetPascalTokenStr(ptFunction)) then
ReadFunction()
else if Tokenizer.TokenSymbolIs(GetPascalTokenStr(ptEnd)) then begin
NextToken();
NextToken();
Break;
end else begin
Error('"%s", "%s", "%s" expected.',[GetPascalTokenStr(ptProcedure),GetPascalTokenStr(ptFunction),GetPascalTokenStr(ptEnd)]);
end;
until ( Tokenizer.Token = toEOF ) ;
end;
procedure TPascalParser.ParseEnumType(const AName: String);
Var
sbl : TEnumTypeDefinition;
tmpStr : String;
sblItem : TEnumItemDefinition;
tmpInt : Integer;
begin
sbl := TEnumTypeDefinition.Create(AName);
FSymbolTable.Add(sbl);
FCurrentSymbol := sbl;
CheckCurrentString(GetPascalTokenStr(ptLeftParenthesis));
NextToken();
Tokenizer.CheckToken(toSymbol);
tmpInt := 0;
Repeat
tmpStr := Tokenizer.TokenString;
If ( FSymbolTable.IndexOf(tmpStr) > -1 ) Then
Error('Duplicated symbol : "%s"',[tmpStr]);
sblItem := TEnumItemDefinition.Create(tmpStr,sbl,tmpInt);
FSymbolTable.Add(sblItem);
sbl.AddItem(sblItem);
NextToken();
If AnsiSameText(Tokenizer.TokenString,GetPascalTokenStr(ptRigthParenthesis)) Then
Break;
If AnsiSameText(Tokenizer.TokenString,GetPascalTokenStr(ptComma)) Then
NextToken();
Tokenizer.CheckToken(toSymbol);
Inc(tmpInt);
Until ( Tokenizer.Token = toEOF ) ;
CheckCurrentString(GetPascalTokenStr(ptRigthParenthesis));
NextToken();
CheckCurrentString(GetPascalTokenStr(ptSemicolon));
NextToken();
end;
procedure TPascalParser.ParseClassType(const AName: String);
Var
sbl : TClassTypeDefinition;
begin
sbl := TClassTypeDefinition.Create(AName);
FSymbolTable.Add(sbl);
FCurrentSymbol := sbl;
CheckCurrentString(GetPascalTokenStr(ptClass));
NextToken();
ReadUntil(GetPascalTokenStr(ptEnd),True);
CheckCurrentString(GetPascalTokenStr(ptEnd));
NextToken();
CheckCurrentString(GetPascalTokenStr(ptSemicolon));
NextToken();
end;
constructor TPascalParser.Create(AStream : TStream; ASymbolTable : TSymbolTable);
begin
Assert(Assigned(AStream));
Assert(Assigned(ASymbolTable));
FStream := AStream;
FTokenizer := TParser.Create(FStream);
FSymbolTable := ASymbolTable;
FSymbolTable.Add(CreateWstInterfaceSymbolTable());
FCurrentSymbol := Nil;
end;
destructor TPascalParser.Destroy();
begin
FTokenizer.Free();
inherited Destroy();
end;
function TPascalParser.Parse(): Boolean;
begin
BeginParsing();
Try
Try
SkipComment();
ParseHeader();
ParseInterfaceSection();
Except
On E : Exception Do Begin
Result := False;
SetErrorMessage(E.Message );
End;
End;
Finally
EndParsing();
End;
end;
end.

File diff suppressed because it is too large Load Diff