-
Notifications
You must be signed in to change notification settings - Fork 0
/
expressionparser.pas
113 lines (102 loc) · 2.86 KB
/
expressionparser.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
{
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; version 2 of the License.
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.
}
// Copyright (c) 2010 - J. Aldo G. de Freitas Junior
Unit
ExpressionParser;
Interface
Uses
Classes,
SysUtils,
ExprScanner,
ExprParser,
ExprNodes,
Variants,
StrUtils;
Type
TExpressionParser = Class(TObject)
Private
fStack : TVirtualMachineStack;
fExpression : String;
fError : Boolean;
fErrorString : String;
fErrorRow : Integer;
fErrorCol : Integer;
Public
Constructor Create(Const aExpression : String; Const aStack : TVirtualMachineStack);
Procedure Evaluate(Const aSingleExpression : Boolean = True);
Property Error : Boolean Read fError;
Property ErrorString : String Read fErrorString;
Property ErrorRow : Integer Read fErrorRow;
Property ErrorCol : Integer Read fErrorCol;
End;
Implementation
{ TExpressionParser }
Constructor TExpressionParser.Create(Const aExpression : String; Const aStack : TVirtualMachineStack);
Begin
Inherited Create;
fExpression := aExpression;
fStack := aStack;
fError := False;
fErrorString := '';
End;
Procedure TExpressionParser.Evaluate(Const aSingleExpression : Boolean = True);
Var
lStringStream : TStringStream;
lSource : TExprSource;
lIntermediary : TMemoryStream;
lScanner : TExprScanner;
lTokenIterator : TExprTokenIterator;
lParser : TExprParser;
lDestination : TSourceNode;
lTmp : String;
Begin
Try
lStringStream := Nil;
lSource := Nil;
lIntermediary := Nil;
lScanner := Nil;
lTokenIterator := Nil;
lParser := Nil;
lDestination := Nil;
Try
lStringStream := TStringStream.Create(fExpression);
lSource := TExprSource.Create(lStringStream, False);
lIntermediary := TMemoryStream.Create;
lScanner := TExprScanner.Create(lSource, lIntermediary, False);
lScanner.Scan;
lTokenIterator := TExprTokenIterator.Create(lIntermediary, False);
lParser := TExprParser.Create(lTokenIterator, False);
If aSingleExpression Then
lDestination := lParser.ParseSource As TSourceNode
Else
lDestination := lParser.ParseParameters As TSourceNode;
lDestination.PropagateStack(fStack);
lDestination.Evaluate;
Finally
FreeAndNil(lStringStream);
FreeAndNil(lSource);
FreeAndNil(lIntermediary);
FreeAndNil(lScanner);
FreeAndNil(lTokenIterator);
FreeAndNil(lParser);
FreeAndNil(lDestination);
End;
Except
On E: Exception Do
Begin
fError := True;
lTmp := E.Message;
fErrorRow := StrToInt(Copy2SymbDel(lTmp, ','));
fErrorCol := StrToInt(Copy2SymbDel(lTmp, ','));
fErrorString := lTmp;
End;
End;
End;
End.