Changeset 127 for branches/generator/URules.pas
- Timestamp:
- Nov 30, 2017, 5:19:57 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/generator/URules.pas
r126 r127 110 110 private 111 111 FModified: Boolean; 112 function GetItemString(Item: TRuleItem; Required: Boolean): string; 112 113 procedure SetModified(AValue: Boolean); 113 114 procedure BuildParser(FileName: string); … … 131 132 implementation 132 133 134 const 135 BooleanText: array[Boolean] of string = ('False', 'True'); 136 133 137 { TGrammer } 138 139 function TGrammer.GetItemString(Item: TRuleItem; Required: Boolean): string; 140 begin 141 Result := ''; 142 case Item.RuleItemType of 143 ritTerminal: Result := 'Expect(''' + 144 StringReplace(Item.Terminal, '''', '''''', [rfReplaceAll]) + ''', ' + BooleanText[Required] + ')'; 145 ritNonTerminal: Result := 'Parse' + Item.NonTerminal.Name + '(' + BooleanText[Required] + ')'; 146 ritTerminalRange: Result := 'ExpectRange(''' + 147 StringReplace(Item.TerminalFrom, '''', '''''', [rfReplaceAll]) + ''', ''' + 148 StringReplace(Item.TerminalTo, '''', '''''', [rfReplaceAll]) + ''', ' + BooleanText[Required] + ')'; 149 //ritSubItems: Line := 'Parse +'; 150 end; 151 end; 134 152 135 153 procedure TGrammer.SetModified(AValue: Boolean); … … 146 164 Line: string; 147 165 Item: TRuleItem; 166 Required: Boolean; 148 167 begin 149 168 ParserFile := TStringList.Create; … … 155 174 Add('interface'); 156 175 Add(''); 176 Add('uses'); 177 Add(' SysUtils;'); 178 Add(''); 157 179 Add('type'); 158 180 Add(' TParser = class'); 159 181 Add(' Content: string;'); 182 Add(' FileName: string;'); 160 183 Add(' Position: Integer;'); 161 184 Add(' procedure Error(Text: string);'); … … 163 186 Add(' function ExpectRange(CharFrom, CharTo: Char; Required: Boolean = False): Boolean;'); 164 187 for Rule in Rules do 165 Add(' function Parse' + Rule.Name + ' : Boolean;');188 Add(' function Parse' + Rule.Name + '(Required: Boolean = False): Boolean;'); 166 189 Add(' constructor Create;'); 167 190 Add(' end;'); … … 176 199 Add('procedure TParser.Error(Text: string);'); 177 200 Add('begin'); 178 Add(' WriteLn( ''Error: '' + Text);');201 Add(' WriteLn(FileName + ''('' + IntToStr(Position) + '') Error: '' + Text);'); 179 202 Add('end;'); 180 203 Add(''); … … 182 205 Add('var'); 183 206 Add(' ReadText: string;'); 207 Add(' StartPos: Integer;'); 184 208 Add('begin'); 209 Add(' StartPos := Position;'); 185 210 Add(' ReadText := Copy(Content, Position, Length(Text));'); 186 211 Add(' Inc(Position, Length(Text));'); 187 212 Add(' Result := Text = ReadText;'); 188 Add(' if not Result and Required then Error(''Expected '' + Text + '' but found '' + ReadText + ''.'');'); 213 Add(' if not Result then begin'); 214 Add(' Position := StartPos;'); 215 Add(' if Required then Error(''Expected "'' + Text + ''" but found "'' + ReadText + ''".'');'); 216 Add(' end;'); 189 217 Add('end;'); 190 218 Add(''); … … 192 220 Add('var'); 193 221 Add(' ReadChar: Char;'); 222 Add(' StartPos: Integer;'); 194 223 Add('begin'); 224 Add(' StartPos := Position;'); 195 225 Add(' ReadChar := Content[Position];'); 196 226 Add(' Inc(Position, 1);'); 197 227 Add(' Result := (ReadChar >= CharFrom) and (ReadChar <= CharTo);'); 198 Add(' if not Result and Required then Error(''Expected '' + CharFrom + '' to '' + CharTo + '' but found '' + ReadChar + ''.'');'); 228 Add(' if not Result then begin'); 229 Add(' Position := StartPos;'); 230 Add(' if Required then Error(''Expected "'' + CharFrom + ''" to "'' + CharTo + ''" but found "'' + ReadChar + ''".'');'); 231 Add(' end;'); 199 232 Add('end;'); 200 233 Add(''); 201 234 for Rule in Rules do begin 202 Add('function TParser.Parse' + Rule.Name + ' : Boolean;');235 Add('function TParser.Parse' + Rule.Name + '(Required: Boolean = False): Boolean;'); 203 236 Add('begin'); 237 Add(' Result := True;'); 204 238 I := 0; 205 239 for Item in Rule.Items do begin 240 Required := not Item.Optional; 206 241 Line := ' '; 207 if Rule.Items.RuleType = rtOr then begin 208 if I > 0 then Line := Line + 'else '; 209 Line := Line + 'if '; 210 end else 211 if Rule.Items.RuleType = rtAnd then begin 212 Line := Line + ''; 213 end; 214 case Item.RuleItemType of 215 ritTerminal: Line := Line + 'Expect(''' + StringReplace(Item.Terminal, '''', '''''', [rfReplaceAll]) + ''')'; 216 ritNonTerminal: Line := Line + 'Parse' + Item.NonTerminal.Name; 217 ritTerminalRange: Line := Line + 'ExpectRange(''' + Item.TerminalFrom + ''', ''' + Item.TerminalTo + ''')'; 218 //ritSubItems: Line := 'Parse +'; 219 end; 220 if Rule.Items.RuleType = rtOr then begin 221 Line := Line + ' then '; 222 end else 223 if Rule.Items.RuleType = rtAnd then begin 224 Line := Line + ';'; 242 case Rule.Items.RuleType of 243 rtOr: begin 244 if I > 0 then Line := Line + 'else '; 245 Line := Line + 'if ' + GetItemString(Item, False); 246 Line := Line + ' then Exit'; 247 end; 248 rtAnd: begin 249 Line := Line + 'Result := Result and '; 250 if Item.Optional then Line := Line + 'True;' + LineEnding; 251 if Item.Repetitive then begin 252 if not Item.Optional then 253 Line := Line + ' ' + GetItemString(Item, Required) + ';' + LineEnding; 254 Line := Line + ' repeat' + LineEnding + ' if not '; 255 Required := False; 256 end; 257 Line := Line + GetItemString(Item, Required); 258 if Item.Repetitive then Line := Line + ' then Break;' + LineEnding + ' until False'; 259 Line := Line + ';' + LineEnding + ' if not Result then Exit;'; 260 end; 225 261 end; 226 262 Add(Line); 227 263 Inc(I); 228 264 end; 229 if Rule.Items.RuleType = rtOr then begin 230 Add(' else ShowError(''Unexpected token'');'); 265 case Rule.Items.RuleType of 266 rtOr: begin 267 Add(' else begin'); 268 Add(' Error(''Unexpected token'');'); 269 Add(' Result := False;'); 270 Add(' end;'); 271 end; 272 //rtAnd: Add(' if not Result then ShowError('''')'); 231 273 end; 232 274 Add('end;'); … … 251 293 Add(''); 252 294 Add('uses'); 253 Add(' Source, Parser ;');295 Add(' Source, Parser, SysUtils;'); 254 296 Add(''); 255 297 Add('procedure Compile(FileName: string);'); … … 262 304 Add(' Reset(SourceFile);'); 263 305 Add(' Parser := TParser.Create;'); 306 Add(' Parser.FileName := ExtractFileName(FileName);'); 264 307 Add(' SetLength(Parser.Content, FileSize(SourceFile));'); 265 308 Add(' I := 1;');
Note:
See TracChangeset
for help on using the changeset viewer.