| 1 | unit Parser;
|
|---|
| 2 |
|
|---|
| 3 | interface
|
|---|
| 4 |
|
|---|
| 5 | uses
|
|---|
| 6 | Classes, SysUtils, Tokenizer, Source;
|
|---|
| 7 |
|
|---|
| 8 | type
|
|---|
| 9 |
|
|---|
| 10 | { TParser }
|
|---|
| 11 |
|
|---|
| 12 | TParser = class
|
|---|
| 13 | private
|
|---|
| 14 | FOnError: TErrorEvent;
|
|---|
| 15 | procedure TokenizerError(Pos: TPoint; Text: string);
|
|---|
| 16 | procedure InitSystemBlock(Block: TBlock);
|
|---|
| 17 | protected
|
|---|
| 18 | Tokenizer: TTokenizer;
|
|---|
| 19 | function ParseProgram(SystemBlock: TBlock; out Prog: TProgram): Boolean; virtual;
|
|---|
| 20 | public
|
|---|
| 21 | Source: string;
|
|---|
| 22 | Prog: TProgram;
|
|---|
| 23 | procedure Parse;
|
|---|
| 24 | procedure Error(Text: string);
|
|---|
| 25 | constructor Create;
|
|---|
| 26 | destructor Destroy; override;
|
|---|
| 27 | property OnError: TErrorEvent read FOnError write FOnError;
|
|---|
| 28 | end;
|
|---|
| 29 |
|
|---|
| 30 |
|
|---|
| 31 | implementation
|
|---|
| 32 |
|
|---|
| 33 | resourcestring
|
|---|
| 34 | SCannotParseProgram = 'Cannot parse program.';
|
|---|
| 35 |
|
|---|
| 36 | { TParser }
|
|---|
| 37 |
|
|---|
| 38 | procedure TParser.TokenizerError(Pos: TPoint; Text: string);
|
|---|
| 39 | begin
|
|---|
| 40 | if Assigned(FOnError) then
|
|---|
| 41 | FOnError(Pos, Text);
|
|---|
| 42 | end;
|
|---|
| 43 |
|
|---|
| 44 | procedure TParser.InitSystemBlock(Block: TBlock);
|
|---|
| 45 | var
|
|---|
| 46 | I: Integer;
|
|---|
| 47 | TypeBoolean: TType;
|
|---|
| 48 | TypeString: TType;
|
|---|
| 49 | TypeInteger: TType;
|
|---|
| 50 | begin
|
|---|
| 51 | TypeBoolean := Block.Types.AddNew('Boolean');
|
|---|
| 52 | with TypeBoolean do begin
|
|---|
| 53 | ValueClass := TValueBoolean;
|
|---|
| 54 | with Functions.AddNew('_Assign') do begin
|
|---|
| 55 | Params.AddNew('Source', TypeBoolean);
|
|---|
| 56 | ResultType := TypeBoolean;
|
|---|
| 57 | end;
|
|---|
| 58 | with Functions.AddNew('_Equal') do begin
|
|---|
| 59 | Params.AddNew('A', TypeBoolean);
|
|---|
| 60 | Params.AddNew('B', TypeBoolean);
|
|---|
| 61 | ResultType := TypeBoolean;
|
|---|
| 62 | end;
|
|---|
| 63 | with Functions.AddNew('_NotEqual') do begin
|
|---|
| 64 | Params.AddNew('A', TypeBoolean);
|
|---|
| 65 | Params.AddNew('B', TypeBoolean);
|
|---|
| 66 | ResultType := TypeBoolean;
|
|---|
| 67 | end;
|
|---|
| 68 | with Functions.AddNew('_Not') do begin
|
|---|
| 69 | Params.AddNew('A', TypeBoolean);
|
|---|
| 70 | ResultType := TypeBoolean;
|
|---|
| 71 | end;
|
|---|
| 72 | end;
|
|---|
| 73 | TypeString := Block.Types.AddNew('string');
|
|---|
| 74 | with TypeString do begin
|
|---|
| 75 | ValueClass := TValueString;
|
|---|
| 76 | with Functions.AddNew('_Assign') do begin
|
|---|
| 77 | Params.AddNew('Source', TypeString);
|
|---|
| 78 | ResultType := TypeString;
|
|---|
| 79 | end;
|
|---|
| 80 | with Functions.AddNew('_Add') do begin
|
|---|
| 81 | Params.AddNew('A', TypeString);
|
|---|
| 82 | Params.AddNew('B', TypeString);
|
|---|
| 83 | ResultType := TypeString;
|
|---|
| 84 | end;
|
|---|
| 85 | with Functions.AddNew('_Equal') do begin
|
|---|
| 86 | Params.AddNew('A', TypeString);
|
|---|
| 87 | Params.AddNew('B', TypeString);
|
|---|
| 88 | ResultType := TypeBoolean;
|
|---|
| 89 | end;
|
|---|
| 90 | with Functions.AddNew('_NotEqual') do begin
|
|---|
| 91 | Params.AddNew('A', TypeString);
|
|---|
| 92 | Params.AddNew('B', TypeString);
|
|---|
| 93 | ResultType := TypeBoolean;
|
|---|
| 94 | end;
|
|---|
| 95 | end;
|
|---|
| 96 | TypeInteger := Block.Types.AddNew('Integer');
|
|---|
| 97 | with TypeInteger do begin
|
|---|
| 98 | ValueClass := TValueInteger;
|
|---|
| 99 | with Functions.AddNew('_Assign') do begin
|
|---|
| 100 | Params.AddNew('Source', TypeInteger);
|
|---|
| 101 | ResultType := TypeInteger;
|
|---|
| 102 | end;
|
|---|
| 103 | with Functions.AddNew('_Add') do begin
|
|---|
| 104 | Params.AddNew('A', TypeInteger);
|
|---|
| 105 | Params.AddNew('B', TypeInteger);
|
|---|
| 106 | ResultType := TypeInteger;
|
|---|
| 107 | end;
|
|---|
| 108 | with Functions.AddNew('_Sub') do begin
|
|---|
| 109 | Params.AddNew('A', TypeInteger);
|
|---|
| 110 | Params.AddNew('B', TypeInteger);
|
|---|
| 111 | ResultType := TypeInteger;
|
|---|
| 112 | end;
|
|---|
| 113 | with Functions.AddNew('_Mul') do begin
|
|---|
| 114 | Params.AddNew('A', TypeInteger);
|
|---|
| 115 | Params.AddNew('B', TypeInteger);
|
|---|
| 116 | ResultType := TypeInteger;
|
|---|
| 117 | end;
|
|---|
| 118 | with Functions.AddNew('_IntDiv') do begin
|
|---|
| 119 | Params.AddNew('A', TypeInteger);
|
|---|
| 120 | Params.AddNew('B', TypeInteger);
|
|---|
| 121 | ResultType := TypeInteger;
|
|---|
| 122 | end;
|
|---|
| 123 | with Functions.AddNew('_Mod') do begin
|
|---|
| 124 | Params.AddNew('A', TypeInteger);
|
|---|
| 125 | Params.AddNew('B', TypeInteger);
|
|---|
| 126 | ResultType := TypeInteger;
|
|---|
| 127 | end;
|
|---|
| 128 | with Functions.AddNew('_Equal') do begin
|
|---|
| 129 | Params.AddNew('A', TypeInteger);
|
|---|
| 130 | Params.AddNew('B', TypeInteger);
|
|---|
| 131 | ResultType := TypeBoolean;
|
|---|
| 132 | end;
|
|---|
| 133 | with Functions.AddNew('_NotEqual') do begin
|
|---|
| 134 | Params.AddNew('A', TypeInteger);
|
|---|
| 135 | Params.AddNew('B', TypeInteger);
|
|---|
| 136 | ResultType := TypeBoolean;
|
|---|
| 137 | end;
|
|---|
| 138 | with Functions.AddNew('_Lesser') do begin
|
|---|
| 139 | Params.AddNew('A', TypeInteger);
|
|---|
| 140 | Params.AddNew('B', TypeInteger);
|
|---|
| 141 | ResultType := TypeBoolean;
|
|---|
| 142 | end;
|
|---|
| 143 | with Functions.AddNew('_Higher') do begin
|
|---|
| 144 | Params.AddNew('A', TypeInteger);
|
|---|
| 145 | Params.AddNew('B', TypeInteger);
|
|---|
| 146 | ResultType := TypeBoolean;
|
|---|
| 147 | end;
|
|---|
| 148 | with Functions.AddNew('_LesserOrEqual') do begin
|
|---|
| 149 | Params.AddNew('A', TypeInteger);
|
|---|
| 150 | Params.AddNew('B', TypeInteger);
|
|---|
| 151 | ResultType := TypeBoolean;
|
|---|
| 152 | end;
|
|---|
| 153 | with Functions.AddNew('_HigherOrEqual') do begin
|
|---|
| 154 | Params.AddNew('A', TypeInteger);
|
|---|
| 155 | Params.AddNew('B', TypeInteger);
|
|---|
| 156 | ResultType := TypeBoolean;
|
|---|
| 157 | end;
|
|---|
| 158 | with Functions.AddNew('_Shr') do begin
|
|---|
| 159 | Params.AddNew('A', TypeInteger);
|
|---|
| 160 | Params.AddNew('B', TypeInteger);
|
|---|
| 161 | ResultType := TypeInteger;
|
|---|
| 162 | end;
|
|---|
| 163 | with Functions.AddNew('_Shl') do begin
|
|---|
| 164 | Params.AddNew('A', TypeInteger);
|
|---|
| 165 | Params.AddNew('B', TypeInteger);
|
|---|
| 166 | ResultType := TypeInteger;
|
|---|
| 167 | end;
|
|---|
| 168 | with Functions.AddNew('_And') do begin
|
|---|
| 169 | Params.AddNew('A', TypeInteger);
|
|---|
| 170 | Params.AddNew('B', TypeInteger);
|
|---|
| 171 | ResultType := TypeInteger;
|
|---|
| 172 | end;
|
|---|
| 173 | with Functions.AddNew('_Or') do begin
|
|---|
| 174 | Params.AddNew('A', TypeInteger);
|
|---|
| 175 | Params.AddNew('B', TypeInteger);
|
|---|
| 176 | ResultType := TypeInteger;
|
|---|
| 177 | end;
|
|---|
| 178 | with Functions.AddNew('_Xor') do begin
|
|---|
| 179 | Params.AddNew('A', TypeInteger);
|
|---|
| 180 | Params.AddNew('B', TypeInteger);
|
|---|
| 181 | ResultType := TypeInteger;
|
|---|
| 182 | end;
|
|---|
| 183 | end;
|
|---|
| 184 | with Block.Functions.AddNew('IntToStr') do begin
|
|---|
| 185 | InternalName := 'IntToStr';
|
|---|
| 186 | Params.AddNew('Value', TypeInteger);
|
|---|
| 187 | ResultType := TypeString;
|
|---|
| 188 | end;
|
|---|
| 189 | with Block.Functions.AddNew('StrToInt') do begin
|
|---|
| 190 | InternalName := 'StrToInt';
|
|---|
| 191 | Params.AddNew('Value', TypeString);
|
|---|
| 192 | ResultType := TypeInteger;
|
|---|
| 193 | end;
|
|---|
| 194 | with Block.Functions.AddNew('BoolToStr') do begin
|
|---|
| 195 | InternalName := 'BoolToStr';
|
|---|
| 196 | Params.AddNew('Value', TypeBoolean);
|
|---|
| 197 | ResultType := TypeString;
|
|---|
| 198 | end;
|
|---|
| 199 | with Block.Functions.AddNew('StrToBool') do begin
|
|---|
| 200 | InternalName := 'StrToBool';
|
|---|
| 201 | Params.AddNew('Value', TypeString);
|
|---|
| 202 | ResultType := TypeBoolean;
|
|---|
| 203 | end;
|
|---|
| 204 | with Block.Procedures.AddNew('WriteLn') do begin
|
|---|
| 205 | InternalName := 'WriteLn';
|
|---|
| 206 | Params.AddNew('Text', TypeString);
|
|---|
| 207 | end;
|
|---|
| 208 | with Block.Procedures.AddNew('Write') do begin
|
|---|
| 209 | InternalName := 'Write';
|
|---|
| 210 | Params.AddNew('Text', TypeString);
|
|---|
| 211 | end;
|
|---|
| 212 | with Block.Procedures.AddNew('ReadLn') do begin
|
|---|
| 213 | InternalName := 'ReadLn';
|
|---|
| 214 | with Params.AddNew('Text', TypeString) do
|
|---|
| 215 | Kind := pkVar;
|
|---|
| 216 | end;
|
|---|
| 217 | with Block.Procedures.AddNew('Read') do begin
|
|---|
| 218 | InternalName := 'Read';
|
|---|
| 219 | with Params.AddNew('Text', TypeString) do
|
|---|
| 220 | Kind := pkVar;
|
|---|
| 221 | end;
|
|---|
| 222 |
|
|---|
| 223 | for I := 0 to Block.Functions.Count - 1 do
|
|---|
| 224 | Block.Functions[I].InitVariables;
|
|---|
| 225 | for I := 0 to Block.Procedures.Count - 1 do
|
|---|
| 226 | Block.Procedures[I].InitVariables;
|
|---|
| 227 | end;
|
|---|
| 228 |
|
|---|
| 229 | function TParser.ParseProgram(SystemBlock: TBlock; out Prog: TProgram): Boolean;
|
|---|
| 230 | begin
|
|---|
| 231 | Result := False;
|
|---|
| 232 | end;
|
|---|
| 233 |
|
|---|
| 234 | procedure TParser.Parse;
|
|---|
| 235 | var
|
|---|
| 236 | NewProg: TProgram;
|
|---|
| 237 | SystemBlock: TBlock;
|
|---|
| 238 | begin
|
|---|
| 239 | Tokenizer.Source := Source;
|
|---|
| 240 | Tokenizer.Init;
|
|---|
| 241 | SystemBlock := TBlock.Create;
|
|---|
| 242 | InitSystemBlock(SystemBlock);
|
|---|
| 243 | if ParseProgram(SystemBlock, NewProg) then begin
|
|---|
| 244 | Prog := NewProg;
|
|---|
| 245 | end else Tokenizer.Error(SCannotParseProgram);
|
|---|
| 246 | end;
|
|---|
| 247 |
|
|---|
| 248 | procedure TParser.Error(Text: string);
|
|---|
| 249 | begin
|
|---|
| 250 | if Assigned(FOnError) then
|
|---|
| 251 | FOnError(Tokenizer.Pos.Pos, Text);
|
|---|
| 252 | end;
|
|---|
| 253 |
|
|---|
| 254 | constructor TParser.Create;
|
|---|
| 255 | begin
|
|---|
| 256 | Tokenizer := TTokenizer.Create;
|
|---|
| 257 | Tokenizer.OnError := TokenizerError;
|
|---|
| 258 | end;
|
|---|
| 259 |
|
|---|
| 260 | destructor TParser.Destroy;
|
|---|
| 261 | begin
|
|---|
| 262 | FreeAndNil(Tokenizer);
|
|---|
| 263 | inherited;
|
|---|
| 264 | end;
|
|---|
| 265 |
|
|---|
| 266 | end.
|
|---|
| 267 |
|
|---|