-
Notifications
You must be signed in to change notification settings - Fork 9
/
Analyser.pas
93 lines (78 loc) · 2.22 KB
/
Analyser.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
unit Analyser;
interface
uses
Parser, SymbolTable, Token;
type
TAnalyser = class(TParser)
public
constructor Create(MaxErrors : integer = 10 ; Includes : AnsiString = ''; SilentMode : integer = 2 ;
LanguageMode : AnsiString = ''; NotShow : AnsiString = '');
protected
SymbolTable : TSymbolTable;
Operand : TToken;
procedure Analyse(Symbol : char); override;
procedure PushScope;
procedure PopScope;
procedure AddModule;
procedure AddSymbol;
procedure SetType;
procedure GetSymbol;
end;
implementation
uses
CompilerUtils;//, Generator;
const
SemanticAction : array[#0..#5] of pointer = (
@TAnalyser.PushScope, @TAnalyser.PopScope, @TAnalyser.AddModule, @TAnalyser.AddSymbol,
@TAnalyser.SetType, @TAnalyser.GetSymbol);
constructor TAnalyser.Create(MaxErrors : integer; Includes : AnsiString; SilentMode : integer; LanguageMode : AnsiString;
NotShow : AnsiString);
begin
inherited;
SymbolTable := TSymbolTable.Create;
end;
procedure TAnalyser.Analyse(Symbol : char); begin
Call(SemanticAction, Symbol);
end;
procedure TAnalyser.PushScope; begin
SymbolTable.PushScope;
end;
procedure TAnalyser.PopScope; begin
try
SymbolTable.PopScope;
except
on E : EFatal do ShowMessage('Fatal', E.Message);
end;
end;
procedure TAnalyser.AddModule; begin
Token.Kind := StringToTokenKind(LastLexeme);
//MakeModule(Token);
AddSymbol;
end;
procedure TAnalyser.AddSymbol; begin
try
SymbolTable.Add(Token);
Token := TToken.Create;
except
on E : EFatal do ShowMessage('Fatal', E.Message);
on E : EError do Error(E.Message);
end;
end;
procedure TAnalyser.SetType;
var
T : TToken;
L : string;
begin
L := Token.Lexeme;
T := SymbolTable.Last;
while (T <> nil) and (T.Kind = tkIdentifier) do begin
T.Type_ := SymbolTable.Get(L);
if T.Type_ = nil then T.Kind := StringToTokenKind(L, tkIdentifier);
T := SymbolTable.Previous;
end;
end;
procedure TAnalyser.GetSymbol; begin
Operand := SymbolTable.Get(Token.Lexeme);
if Operand = nil then Error('Undeclared Identifier "' + Token.Lexeme + '"');
end;
end.