Changeset 125 for branches/generator/URules.pas
- Timestamp:
- Nov 29, 2017, 6:31:25 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/generator/URules.pas
r124 r125 111 111 FModified: Boolean; 112 112 procedure SetModified(AValue: Boolean); 113 procedure BuildParser(FileName: string); 113 114 procedure BuildMain(FileName: string); 114 115 procedure BuildSource(FileName: string); … … 137 138 end; 138 139 139 procedure TGrammer.Build Main(FileName: string);140 procedure TGrammer.BuildParser(FileName: string); 140 141 var 141 142 ParserFile: TStringList; 143 Rule: TRule; 144 I: Integer; 145 Line: string; 146 Item: TRuleItem; 142 147 begin 143 148 ParserFile := TStringList.Create; 144 149 with ParserFile do begin 145 Add(' program Compiler;');150 Add('unit Parse;'); 146 151 Add(''); 147 152 Add('{$MODE Delphi}'); 148 153 Add(''); 149 Add('uses'); 150 Add(' Source;'); 151 Add(''); 152 Add('procedure Compile(FileName: string);'); 154 Add('interface'); 155 Add(''); 156 Add('type'); 157 Add(' TParser = class'); 158 Add(' Content: string;'); 159 Add(' Position: Integer;'); 160 Add(' function Expect(Text: string; Required: Boolean = False): Boolean;'); 161 Add(' function ExpectRange(CharFrom, CharTo: Char; Required: Boolean = False): Boolean;'); 162 for Rule in Rules do 163 Add(' function Parse' + Rule.Name + ': Boolean;'); 164 Add(' end;'); 165 Add(''); 166 Add('implementation'); 167 Add(''); 168 Add('function TParser.Expect(Text: string; Required: Boolean = False): Boolean;'); 153 169 Add('var'); 154 Add(' SourceFile: Text;');170 Add(' ReadText: string;'); 155 171 Add('begin'); 156 Add(' AssignFile(SourceFile, FileName);'); 157 Add(' Reset(SourceFile);'); 158 Add(' SetLength(Content, FileSize(SourceFile));'); 159 Add(' Read(SourceFile, Content);'); 160 if Assigned(TopRule) then 161 Add(' Parse' + TopRule.Name + ';'); 162 Add(' CloseFile(SourceFile);'); 172 Add(' ReadText := Copy(Content, Position, Length(Text));'); 173 Add(' Inc(Position, Length(Text));'); 174 Add(' Result := Text = ReadText'); 175 Add(' if not Result and Required then Error(''Expected '' + Text + '' but found '' + ReadText + ''.'');'); 163 176 Add('end;'); 164 177 Add(''); 178 Add('function TParser.ExpectRange(CharFrom, CharTo: char; Required: Boolean = False): Boolean;'); 179 Add('var'); 180 Add(' ReadChar: Char;'); 165 181 Add('begin'); 166 Add(' if ParamCount > 1 then'); 167 Add(' Compile(ParamStr(1));'); 168 Add('end.'); 169 SaveToFile(FileName); 170 end; 171 FreeAndNil(ParserFile); 172 end; 173 174 procedure TGrammer.BuildSource(FileName: string); 175 var 176 Rule: TRule; 177 Item: TRuleItem; 178 Line: string; 179 I: Integer; 180 SourceFile: TStringList; 181 begin 182 SourceFile := TStringList.Create; 183 with SourceFile do begin 184 Add('unit Source;'); 185 Add(''); 186 Add('{$MODE Delphi}'); 187 Add(''); 188 Add('interface'); 189 Add(''); 190 Add('uses'); 191 Add(' fgl;'); 192 Add(''); 193 Add('type'); 194 for Rule in Rules do 195 if Rule.CreateSourceNode then begin 196 Add(' T' + Rule.Name + ' = class;'); 197 end; 198 Add(''); 199 for Rule in Rules do 200 if Rule.CreateSourceNode then begin 201 Add(' T' + Rule.Name + ' = class'); 202 for Item in Rule.Items do begin 203 if Item.RuleItemType = ritNonTerminal then 204 if Item.Repetitive then 205 Add(' ' + Item.NonTerminal.Name + ': TFPGObjectList<T' + Item.NonTerminal.Name + '>;') 206 else Add(' ' + Item.NonTerminal.Name + ': T' + Item.NonTerminal.Name + ';'); 207 end; 208 Add(' end;' + LineEnding); 209 end; 210 Add(''); 211 Add('implementation'); 182 Add(' ReadChar := Content[Position];'); 183 Add(' Inc(Position, 1);'); 184 Add(' Result := (ReadChar >= CharFrom) and (ReadChar <= CharTo);'); 185 Add(' if not Result and Required then Error(''Expected '' + CharFrom + '' to '' + CharTo + '' but found '' + ReadChar + ''.'');'); 186 Add('end;'); 212 187 Add(''); 213 188 for Rule in Rules do begin 214 Add('function Parse' + Rule.Name + ': Boolean;');189 Add('function TParser.Parse' + Rule.Name + ': Boolean;'); 215 190 Add('begin'); 216 191 I := 0; … … 225 200 end; 226 201 case Item.RuleItemType of 227 ritTerminal: Line := Line + 'Expect(''' + Item.Terminal+ ''')';202 ritTerminal: Line := Line + 'Expect(''' + StringReplace(Item.Terminal, '''', '''''', [rfReplaceAll]) + ''')'; 228 203 ritNonTerminal: Line := Line + 'Parse' + Item.NonTerminal.Name; 229 ritTerminalRange: Line := Line + 'Expect(''' + Item.Terminal + ''')'; 204 ritTerminalRange: Line := Line + 'ExpectRange(''' + Item.TerminalFrom + ''', ''' + Item.TerminalTo + ''')'; 205 //ritSubItems: Line := 'Parse +'; 230 206 end; 231 207 if Rule.Items.RuleType = rtOr then begin … … 244 220 Add(''); 245 221 end; 222 Add(''); 223 Add('end.'); 224 SaveToFile(FileName); 225 end; 226 FreeAndNil(ParserFile); 227 end; 228 229 procedure TGrammer.BuildMain(FileName: string); 230 var 231 ParserFile: TStringList; 232 begin 233 ParserFile := TStringList.Create; 234 with ParserFile do begin 235 Add('program Compiler;'); 236 Add(''); 237 Add('{$MODE Delphi}'); 238 Add(''); 239 Add('uses'); 240 Add(' Source, Parser;'); 241 Add(''); 242 Add('procedure Compile(FileName: string);'); 243 Add('var'); 244 Add(' SourceFile: Text;'); 245 Add('begin'); 246 Add(' AssignFile(SourceFile, FileName);'); 247 Add(' Reset(SourceFile);'); 248 Add(' SetLength(Content, FileSize(SourceFile));'); 249 Add(' Parser := TParser.Create;'); 250 Add(' Read(SourceFile, Parser.Content);'); 251 Add(' CloseFile(SourceFile);'); 252 if Assigned(TopRule) then 253 Add(' Parser.Parse' + TopRule.Name + ';'); 254 Add(' Parser.Free;'); 255 Add('end;'); 256 Add(''); 257 Add('begin'); 258 Add(' if ParamCount > 1 then'); 259 Add(' Compile(ParamStr(1));'); 260 Add('end.'); 261 SaveToFile(FileName); 262 end; 263 FreeAndNil(ParserFile); 264 end; 265 266 procedure TGrammer.BuildSource(FileName: string); 267 var 268 Rule: TRule; 269 Item: TRuleItem; 270 SourceFile: TStringList; 271 begin 272 SourceFile := TStringList.Create; 273 with SourceFile do begin 274 Add('unit Source;'); 275 Add(''); 276 Add('{$MODE Delphi}'); 277 Add(''); 278 Add('interface'); 279 Add(''); 280 Add('uses'); 281 Add(' fgl;'); 282 Add(''); 283 Add('type'); 284 for Rule in Rules do 285 if Rule.CreateSourceNode then begin 286 Add(' T' + Rule.Name + ' = class;'); 287 end; 288 Add(''); 289 for Rule in Rules do 290 if Rule.CreateSourceNode then begin 291 Add(' T' + Rule.Name + ' = class'); 292 for Item in Rule.Items do begin 293 if Item.RuleItemType = ritNonTerminal then 294 if Item.Repetitive then 295 Add(' ' + Item.NonTerminal.Name + ': TFPGObjectList<T' + Item.NonTerminal.Name + '>;') 296 else Add(' ' + Item.NonTerminal.Name + ': T' + Item.NonTerminal.Name + ';'); 297 end; 298 Add(' end;' + LineEnding); 299 end; 300 Add(''); 301 Add('implementation'); 302 Add(''); 246 303 247 304 Add('end.'); … … 258 315 RulesNode: TDOMNode; 259 316 Rule: TRule; 260 TopRuleName: string;261 317 begin 262 318 Self.FileName := FileName; … … 329 385 330 386 BuildMain(OutputDir + DirectorySeparator + 'Compiler.pas'); 331 BuildSource(OutputDir + DirectorySeparator +'Source.pas'); 387 BuildSource(OutputDir + DirectorySeparator + 'Source.pas'); 388 BuildParser(OutputDir + DirectorySeparator + 'Parser.pas'); 332 389 end; 333 390
Note:
See TracChangeset
for help on using the changeset viewer.