|
@@ -1,6 +1,6 @@
|
|
|
unit jsparser;
|
|
|
|
|
|
-{$define debugparser}
|
|
|
+{ $define debugparser}
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
|
|
interface
|
|
@@ -140,6 +140,7 @@ Type
|
|
|
Public
|
|
|
Constructor Create(AInput: TStream);
|
|
|
Constructor Create(AScanner : TJSScanner);
|
|
|
+ Destructor Destroy; override;
|
|
|
Function Parse : TJSElement;
|
|
|
Function ParseProgram : TJSFunctionDeclarationStatement;
|
|
|
Function CurrentToken : TJSToken;
|
|
@@ -182,18 +183,18 @@ Resourcestring
|
|
|
|
|
|
{ TJSScanner }
|
|
|
|
|
|
-function TJSParser.CurrentToken: TJSToken;
|
|
|
+Function TJSParser.CurrentToken: TJSToken;
|
|
|
|
|
|
begin
|
|
|
Result:=FCurrent;
|
|
|
end;
|
|
|
|
|
|
-function TJSParser.CurrentTokenString: String;
|
|
|
+Function TJSParser.CurrentTokenString: String;
|
|
|
begin
|
|
|
Result:=FCurrentString;
|
|
|
end;
|
|
|
|
|
|
-function TJSParser.GetNextToken: TJSToken;
|
|
|
+Function TJSParser.GetNextToken: TJSToken;
|
|
|
begin
|
|
|
FPrevious:=FCurrent;
|
|
|
If (FPeekToken<>tjsunknown) then
|
|
@@ -211,7 +212,7 @@ begin
|
|
|
{$ifdef debugparser}Writeln('GetNextToken (',FScanner.CurLine,',',FScanner.CurColumn,'): ',GetEnumName(TypeInfo(TJSToken),Ord(FCurrent)), ' As string: ',FCurrentString);{$endif debugparser}
|
|
|
end;
|
|
|
|
|
|
-function TJSParser.PeekNextToken: TJSToken;
|
|
|
+Function TJSParser.PeekNextToken: TJSToken;
|
|
|
begin
|
|
|
If (FPeekToken=tjsUnknown) then
|
|
|
begin
|
|
@@ -222,13 +223,13 @@ begin
|
|
|
Result:=FPeekToken;
|
|
|
end;
|
|
|
|
|
|
-function TJSParser.IsEndOfLine: Boolean;
|
|
|
+Function TJSParser.IsEndOfLine: Boolean;
|
|
|
begin
|
|
|
Result:=FScanner.IsEndOfLine;
|
|
|
end;
|
|
|
|
|
|
|
|
|
-function TJSParser.CurPos: Integer;
|
|
|
+Function TJSParser.CurPos: Integer;
|
|
|
begin
|
|
|
If Assigned(FScanner) then
|
|
|
Result:=FScanner.CurColumn
|
|
@@ -236,7 +237,7 @@ begin
|
|
|
Result:=0;
|
|
|
end;
|
|
|
|
|
|
-function TJSParser.CurLine: Integer;
|
|
|
+Function TJSParser.CurLine: Integer;
|
|
|
begin
|
|
|
If Assigned(FScanner) then
|
|
|
Result:=FScanner.CurRow
|
|
@@ -252,12 +253,12 @@ begin
|
|
|
Result:='';
|
|
|
end;
|
|
|
|
|
|
-procedure TJSParser.CheckParser;
|
|
|
+Procedure TJSParser.CheckParser;
|
|
|
begin
|
|
|
|
|
|
end;
|
|
|
|
|
|
-Procedure TJSParser.LeaveLabel;
|
|
|
+procedure TJSParser.LeaveLabel;
|
|
|
|
|
|
Var
|
|
|
L : TJSLabel;
|
|
@@ -324,7 +325,7 @@ begin
|
|
|
Result:=L;
|
|
|
end;
|
|
|
|
|
|
-function TJSParser.CurrentLabelSet: TJSLabelSet;
|
|
|
+Function TJSParser.CurrentLabelSet: TJSLabelSet;
|
|
|
|
|
|
Var
|
|
|
LS : TJSLabelSet;
|
|
@@ -344,12 +345,12 @@ begin
|
|
|
Result:=FCurrentLabelSet;
|
|
|
end;
|
|
|
|
|
|
-function TJSParser.CreateElement(AElementClass: TJSElementClass): TJSElement;
|
|
|
+Function TJSParser.CreateElement(AElementClass: TJSElementClass): TJSElement;
|
|
|
begin
|
|
|
Result:=AElementClass.Create(CurLine,CurPos,CurSource);
|
|
|
end;
|
|
|
|
|
|
-procedure TJSParser.Error(Msg: String);
|
|
|
+Procedure TJSParser.Error(Msg: String);
|
|
|
|
|
|
Var
|
|
|
ErrAt : String;
|
|
@@ -363,12 +364,12 @@ begin
|
|
|
Raise Exception.Create(ErrAt+Msg)
|
|
|
end;
|
|
|
|
|
|
-procedure TJSParser.Error(Fmt: String; Args: array of const);
|
|
|
+Procedure TJSParser.Error(Fmt: String; Args: Array of const);
|
|
|
begin
|
|
|
Error(Format(Fmt,Args));
|
|
|
end;
|
|
|
|
|
|
-constructor TJSParser.Create(AInput: TStream);
|
|
|
+Constructor TJSParser.Create(AInput: TStream);
|
|
|
begin
|
|
|
FInput:=AInput;
|
|
|
FCurrent:=TJSUnknown;
|
|
@@ -376,16 +377,23 @@ begin
|
|
|
FFreeScanner:=True;
|
|
|
end;
|
|
|
|
|
|
-constructor TJSParser.Create(AScanner: TJSScanner);
|
|
|
+Constructor TJSParser.Create(AScanner: TJSScanner);
|
|
|
begin
|
|
|
FCurrent:=TJSUnknown;
|
|
|
FScanner:=AScanner;
|
|
|
FFreeScanner:=False;
|
|
|
end;
|
|
|
|
|
|
+Destructor TJSParser.Destroy;
|
|
|
+begin
|
|
|
+ if FFreeScanner then
|
|
|
+ FreeAndNil(FScanner);
|
|
|
+ inherited;
|
|
|
+end;
|
|
|
+
|
|
|
|
|
|
|
|
|
-Procedure TJSParser.Expect(aToken : TJSToken);
|
|
|
+procedure TJSParser.Expect(aToken: TJSToken);
|
|
|
|
|
|
begin
|
|
|
{$ifdef debugparser} Writeln('Expecting : ',GetEnumName(TypeInfo(TJSToken),Ord(AToken)), ' As string: ',TokenInfos[AToken]);{$endif debugparser}
|
|
@@ -406,7 +414,7 @@ begin
|
|
|
end;
|
|
|
end;
|
|
|
|
|
|
-procedure TJSParser.Consume(aToken: TJSToken; AllowSemiColonInsert : Boolean = False);
|
|
|
+procedure TJSParser.Consume(aToken: TJSToken; AllowSemicolonInsert: Boolean);
|
|
|
begin
|
|
|
{$ifdef debugparser} Writeln('Consuming : ',GetEnumName(TypeInfo(TJSToken),Ord(AToken)), ' As string: ',TokenInfos[AToken]);{$endif debugparser}
|
|
|
Expect(aToken);
|
|
@@ -540,7 +548,7 @@ begin
|
|
|
{$ifdef debugparser} Writeln('<<< ParseBlock');{$endif debugparser}
|
|
|
end;
|
|
|
|
|
|
-Function TJSParser.ParseArrayLiteral : TJSElement;
|
|
|
+function TJSParser.ParseArrayLiteral: TJSElement;
|
|
|
|
|
|
Var
|
|
|
N : TJSArrayLiteral;
|
|
@@ -577,7 +585,7 @@ begin
|
|
|
end;
|
|
|
end;
|
|
|
|
|
|
-Function TJSParser.ParseObjectLiteral : TJSElement;
|
|
|
+function TJSParser.ParseObjectLiteral: TJSElement;
|
|
|
|
|
|
Var
|
|
|
N : TJSObjectLiteral;
|
|
@@ -615,7 +623,7 @@ begin
|
|
|
end;
|
|
|
end;
|
|
|
|
|
|
-Function TJSParser.ParseNumericLiteral : TJSElement;
|
|
|
+function TJSParser.ParseNumericLiteral: TJSElement;
|
|
|
|
|
|
Var
|
|
|
L : TJSLiteral;
|
|
@@ -639,7 +647,7 @@ begin
|
|
|
end;
|
|
|
end;
|
|
|
|
|
|
-Function TJSParser.ParseStringLiteral : TJSElement;
|
|
|
+function TJSParser.ParseStringLiteral: TJSElement;
|
|
|
|
|
|
Var
|
|
|
L : TJSLiteral;
|
|
@@ -660,7 +668,7 @@ begin
|
|
|
end;
|
|
|
end;
|
|
|
|
|
|
-Function TJSParser.ParseRegularExpressionLiteral : TJSElement;
|
|
|
+function TJSParser.ParseRegularExpressionLiteral: TJSElement;
|
|
|
|
|
|
Var
|
|
|
S,pa,fl : String;
|
|
@@ -693,7 +701,7 @@ begin
|
|
|
end;
|
|
|
end;
|
|
|
|
|
|
-Function TJSParser.ParseLiteral : TJSElement;
|
|
|
+function TJSParser.ParseLiteral: TJSElement;
|
|
|
|
|
|
Var
|
|
|
L : TJSLiteral;
|
|
@@ -724,7 +732,7 @@ begin
|
|
|
end;
|
|
|
end;
|
|
|
|
|
|
-Function TJSParser.ParsePrimaryExpression : TJSElement;
|
|
|
+function TJSParser.ParsePrimaryExpression: TJSElement;
|
|
|
|
|
|
Var
|
|
|
R : TJSPrimaryExpressionIdent;
|
|
@@ -743,18 +751,16 @@ begin
|
|
|
begin
|
|
|
R:=TJSPrimaryExpressionIdent(CreateElement(TJSPrimaryExpressionIdent));
|
|
|
Result:=R;
|
|
|
- R.AString:=CurrentTokenString;
|
|
|
+ R.Name:=CurrentTokenString;
|
|
|
GetNextToken;
|
|
|
end;
|
|
|
tjsSquaredBraceOpen: Result:=ParseArrayLiteral;
|
|
|
tjsCurlyBraceOpen: Result:=ParseObjectLiteral;
|
|
|
tjsBraceOpen:
|
|
|
begin
|
|
|
- Writeln('Found brace !!');
|
|
|
Consume(tjsBraceOpen);
|
|
|
Result:=ParseExpression;
|
|
|
Consume(tjsBraceClose);
|
|
|
- Writeln('Closed brace !!');
|
|
|
end;
|
|
|
else
|
|
|
Result:=ParseLiteral;
|
|
@@ -767,7 +773,7 @@ begin
|
|
|
end;
|
|
|
|
|
|
|
|
|
-Function TJSParser.ParseMemberExpression : TJSElement;
|
|
|
+function TJSParser.ParseMemberExpression: TJSElement;
|
|
|
|
|
|
Var
|
|
|
M : TJSDotMemberExpression;
|
|
@@ -821,7 +827,7 @@ begin
|
|
|
{$ifdef debugparser} Writeln('Exit ParseMemberExpression');{$endif debugparser}
|
|
|
end;
|
|
|
|
|
|
-Function TJSParser.ParseArguments : TJSarguments;
|
|
|
+function TJSParser.ParseArguments: TJSarguments;
|
|
|
|
|
|
Var
|
|
|
E : TJSArrayLiteralElement;
|
|
@@ -847,7 +853,7 @@ begin
|
|
|
end;
|
|
|
end;
|
|
|
|
|
|
-Function TJSParser.ParseLeftHandSideExpression : TJSElement;
|
|
|
+function TJSParser.ParseLeftHandSideExpression: TJSElement;
|
|
|
|
|
|
Var
|
|
|
M : TJSDotMemberExpression;
|
|
@@ -888,7 +894,6 @@ begin
|
|
|
end;
|
|
|
tjsBraceOpen:
|
|
|
begin
|
|
|
- Writeln('Call expression !!');
|
|
|
C:=TJSCallExpression(CreateElement(TJSCallExpression));
|
|
|
C.Expr:=Result;
|
|
|
Result:=C;
|
|
@@ -907,7 +912,7 @@ begin
|
|
|
{$ifdef debugparser} Writeln('Exit ParseLeftHandSideExpression');{$endif debugparser}
|
|
|
end;
|
|
|
|
|
|
-Function TJSParser.ParsePostFixExpression : TJSElement;
|
|
|
+function TJSParser.ParsePostFixExpression: TJSElement;
|
|
|
Var
|
|
|
R : TJSUnaryExpression;
|
|
|
|
|
@@ -933,7 +938,7 @@ begin
|
|
|
{$ifdef debugparser} Writeln('Exit ParsePostfixExpression');{$endif debugparser}
|
|
|
end;
|
|
|
|
|
|
-Function TJSParser.ParseUnaryExpression : TJSElement;
|
|
|
+function TJSParser.ParseUnaryExpression: TJSElement;
|
|
|
|
|
|
Var
|
|
|
C : TJSElementClass;
|
|
@@ -973,7 +978,7 @@ begin
|
|
|
{$ifdef debugparser} Writeln('Exit ParseUnaryExpression');{$endif debugparser}
|
|
|
end;
|
|
|
|
|
|
-Function TJSParser.ParseMultiplicativeExpression : TJSElement;
|
|
|
+function TJSParser.ParseMultiplicativeExpression: TJSElement;
|
|
|
|
|
|
Var
|
|
|
C : TJSElementClass;
|
|
@@ -1005,7 +1010,7 @@ begin
|
|
|
{$ifdef debugparser} Writeln('Exit ParseMultiplicativeExpression');{$endif debugparser}
|
|
|
end;
|
|
|
|
|
|
-Function TJSParser.ParseAdditiveExpression : TJSElement;
|
|
|
+function TJSParser.ParseAdditiveExpression: TJSElement;
|
|
|
|
|
|
Var
|
|
|
C : TJSElementClass;
|
|
@@ -1035,7 +1040,7 @@ begin
|
|
|
{$ifdef debugparser} Writeln('Exit ParseAdditiveExpression');{$endif debugparser}
|
|
|
end;
|
|
|
|
|
|
-Function TJSParser.ParseShiftExpression : TJSElement;
|
|
|
+function TJSParser.ParseShiftExpression: TJSElement;
|
|
|
|
|
|
Var
|
|
|
C : TJSElementClass;
|
|
@@ -1066,7 +1071,7 @@ begin
|
|
|
{$ifdef debugparser} Writeln('Exit ParseShiftExpression');{$endif debugparser}
|
|
|
end;
|
|
|
|
|
|
-Function TJSParser.ParseRelationalExpression: TJSElement;
|
|
|
+function TJSParser.ParseRelationalExpression: TJSElement;
|
|
|
|
|
|
Var
|
|
|
S : Set of TJSToken;
|
|
@@ -1104,7 +1109,7 @@ begin
|
|
|
{$ifdef debugparser} Writeln('Exit ParseRelationalExpression');{$endif debugparser}
|
|
|
end;
|
|
|
|
|
|
-Function TJSParser.ParseEqualityExpression: TJSElement;
|
|
|
+function TJSParser.ParseEqualityExpression: TJSElement;
|
|
|
|
|
|
Var
|
|
|
C : TJSElementClass;
|
|
@@ -1137,7 +1142,7 @@ begin
|
|
|
{$ifdef debugparser} Writeln('Exit ParseEqualityExpression');{$endif debugparser}
|
|
|
end;
|
|
|
|
|
|
-Function TJSParser.ParseBitwiseAndExpression : TJSElement;
|
|
|
+function TJSParser.ParseBitwiseAndExpression: TJSElement;
|
|
|
|
|
|
Var
|
|
|
L : TJSBitwiseAndExpression;
|
|
@@ -1161,7 +1166,7 @@ begin
|
|
|
{$ifdef debugparser} Writeln('Exit ParseBitwiseAndExpression');{$endif debugparser}
|
|
|
end;
|
|
|
|
|
|
-Function TJSParser.ParseBitwiseXORExpression : TJSElement;
|
|
|
+function TJSParser.ParseBitwiseXORExpression: TJSElement;
|
|
|
|
|
|
Var
|
|
|
L : TJSBitwiseXOrExpression;
|
|
@@ -1185,7 +1190,7 @@ begin
|
|
|
{$ifdef debugparser} Writeln('Exit ParseBitwiseXorExpression');{$endif debugparser}
|
|
|
end;
|
|
|
|
|
|
-Function TJSParser.ParseBitwiseORExpression : TJSElement;
|
|
|
+function TJSParser.ParseBitwiseORExpression: TJSElement;
|
|
|
|
|
|
Var
|
|
|
L : TJSBitwiseOrExpression;
|
|
@@ -1209,7 +1214,7 @@ begin
|
|
|
{$ifdef debugparser} Writeln('Exit ParseBitWiseOrExpression');{$endif debugparser}
|
|
|
end;
|
|
|
|
|
|
-Function TJSParser.ParseLogicalAndExpression : TJSElement;
|
|
|
+function TJSParser.ParseLogicalAndExpression: TJSElement;
|
|
|
|
|
|
Var
|
|
|
L : TJSLogicalAndExpression;
|
|
@@ -1233,7 +1238,7 @@ begin
|
|
|
{$ifdef debugparser} Writeln('Exit ParseLogicalAndExpression');{$endif debugparser}
|
|
|
end;
|
|
|
|
|
|
-Function TJSParser.ParseLogicalORExpression : TJSElement;
|
|
|
+function TJSParser.ParseLogicalORExpression: TJSElement;
|
|
|
|
|
|
Var
|
|
|
L : TJSLogicalOrExpression;
|
|
@@ -1245,13 +1250,10 @@ begin
|
|
|
If (CurrentToken<>tjsOROR) then
|
|
|
exit;
|
|
|
GetNextToken;
|
|
|
- Writeln('a');
|
|
|
L:=TJSLogicalOrExpression(CreateElement(TJSLogicalOrExpression));
|
|
|
L.A:=Result;
|
|
|
- Writeln('B');
|
|
|
Result:=L;
|
|
|
L.B:=ParseLogicalOrExpression();
|
|
|
- Writeln('C');
|
|
|
IsLHS:=False;
|
|
|
except
|
|
|
FreeAndNil(Result);
|
|
@@ -1260,7 +1262,7 @@ begin
|
|
|
{$ifdef debugparser} Writeln('Exit ParseLogicalOrExpression');{$endif debugparser}
|
|
|
end;
|
|
|
|
|
|
-Function TJSParser.ParseConditionalExpression : TJSElement;
|
|
|
+function TJSParser.ParseConditionalExpression: TJSElement;
|
|
|
|
|
|
Var
|
|
|
N : TJSConditionalExpression;
|
|
@@ -1290,7 +1292,7 @@ begin
|
|
|
{$ifdef debugparser} Writeln('Exit ParseConditionalExpression');{$endif debugparser}
|
|
|
end;
|
|
|
|
|
|
-Function TJSParser.ParseAssignmentExpression : TJSElement;
|
|
|
+function TJSParser.ParseAssignmentExpression: TJSElement;
|
|
|
|
|
|
Var
|
|
|
N : TJSElement;
|
|
@@ -1343,7 +1345,7 @@ begin
|
|
|
{$ifdef debugparser} Writeln('Exit ParseAssignmentExpression');{$endif debugparser}
|
|
|
end;
|
|
|
|
|
|
-Function TJSParser.ParseVariableDeclaration : TJSElement;
|
|
|
+function TJSParser.ParseVariableDeclaration: TJSElement;
|
|
|
|
|
|
Var
|
|
|
V : TJSVarDeclaration;
|
|
@@ -1360,9 +1362,7 @@ begin
|
|
|
V.Init:=ParseAssignmentExpression;
|
|
|
end;
|
|
|
Result:=V;
|
|
|
- Writeln('Adding variable ',V.Name);
|
|
|
FCurrentVars.AddNode.Node:=Result;
|
|
|
- Writeln('Current var count: ',FCurrentVars.Count);
|
|
|
except
|
|
|
FreeAndNil(V);
|
|
|
Raise;
|
|
@@ -1370,14 +1370,14 @@ begin
|
|
|
{$ifdef debugparser} Writeln('Exit ParseVariableDeclaration');{$endif debugparser}
|
|
|
end;
|
|
|
|
|
|
-Function TJSParser.ParseVariableDeclarationList : TJSElement;
|
|
|
+function TJSParser.ParseVariableDeclarationList: TJSElement;
|
|
|
|
|
|
Var
|
|
|
E,N : TJSElement;
|
|
|
L : TJSVariableDeclarationList;
|
|
|
|
|
|
begin
|
|
|
- Writeln('ParseVariableDeclarationList entry');
|
|
|
+ {$ifdef debugparser} Writeln('ParseVariableDeclarationList entry');{$endif debugparser}
|
|
|
E:=ParseVariableDeclaration;
|
|
|
If (CurrentToken<>tjsComma) then
|
|
|
Result:=E
|
|
@@ -1395,7 +1395,7 @@ begin
|
|
|
Raise;
|
|
|
end;
|
|
|
end;
|
|
|
- Writeln('ParseVariableDeclarationList exit');
|
|
|
+ {$ifdef debugparser} Writeln('ParseVariableDeclarationList exit');{$endif debugparser}
|
|
|
end;
|
|
|
|
|
|
function TJSParser.ParseVariableStatement : TJSElement;
|
|
@@ -1405,7 +1405,7 @@ Var
|
|
|
V : TJSVariableStatement;
|
|
|
|
|
|
begin
|
|
|
- Writeln('ParseVariableStatement entry');
|
|
|
+ {$ifdef debugparser} Writeln('ParseVariableStatement entry');{$endif debugparser}
|
|
|
Result:=Nil;
|
|
|
Consume(tjsVar);
|
|
|
Result:=ParseVariableDeclarationList;
|
|
@@ -1418,7 +1418,7 @@ begin
|
|
|
FreeAndNil(Result);
|
|
|
Raise;
|
|
|
end;
|
|
|
- Writeln('ParseVariableStatement exit');
|
|
|
+ {$ifdef debugparser} Writeln('ParseVariableStatement exit');{$endif debugparser}
|
|
|
end;
|
|
|
|
|
|
function TJSParser.ParseEmptyStatement : TJSElement;
|
|
@@ -1574,6 +1574,7 @@ begin
|
|
|
end; // Case
|
|
|
Finally
|
|
|
LeaveLabel;
|
|
|
+ FreeCurrentLabelSet;
|
|
|
end;
|
|
|
except
|
|
|
FreeAndNil(N);
|
|
@@ -1877,7 +1878,7 @@ begin
|
|
|
try
|
|
|
F:=ParseFunctionExpression;
|
|
|
I:=TJSPrimaryExpressionIdent(CreateElement(TJSPrimaryExpressionIdent));
|
|
|
- I.AString:=F.AFunction.Name;
|
|
|
+ I.Name:=F.AFunction.Name;
|
|
|
A:=TJSAssignStatement(CreateElement(TJSAssignStatement));
|
|
|
A.LHS:=I;
|
|
|
I:=Nil;
|
|
@@ -2110,7 +2111,7 @@ begin
|
|
|
{$ifdef debugparser} Writeln('<<< Exiting FunctionBody');{$endif}
|
|
|
end;
|
|
|
|
|
|
-function TJSParser.ParseProgram : TJSFunctionDeclarationStatement;
|
|
|
+Function TJSParser.ParseProgram: TJSFunctionDeclarationStatement;
|
|
|
|
|
|
Var
|
|
|
F : TJSFunctionDeclarationStatement;
|
|
@@ -2127,7 +2128,7 @@ begin
|
|
|
{$ifdef debugparser} Writeln('<<< Exiting FunctionDeclarationStatement');{$endif}
|
|
|
end;
|
|
|
|
|
|
-function TJSParser.Parse: TJSElement;
|
|
|
+Function TJSParser.Parse: TJSElement;
|
|
|
|
|
|
Var
|
|
|
Body : TJSElement;
|