Changeset 125
- Timestamp:
- Nov 29, 2017, 6:31:25 PM (7 years ago)
- Location:
- branches/generator
- Files:
-
- 2 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 -
branches/generator/pascal.grm
r124 r125 283 283 </RuleItem> 284 284 <RuleItem> 285 <Type>1</Type> 286 <Optional>-1</Optional> 287 <Repetitive>-1</Repetitive> 288 <AnyExcept>0</AnyExcept> 289 <NonTerminal>CaseOfState</NonTerminal> 290 </RuleItem> 291 <RuleItem> 292 <Type>2</Type> 293 <Optional>-1</Optional> 294 <Repetitive>0</Repetitive> 295 <AnyExcept>0</AnyExcept> 296 <SubItems> 297 <Type>0</Type> 298 <RuleItem> 299 <Type>0</Type> 300 <Optional>0</Optional> 301 <Repetitive>0</Repetitive> 302 <AnyExcept>0</AnyExcept> 303 <Terminal>else</Terminal> 304 </RuleItem> 305 <RuleItem> 306 <Type>1</Type> 307 <Optional>0</Optional> 308 <Repetitive>0</Repetitive> 309 <AnyExcept>0</AnyExcept> 310 <NonTerminal>Statement</NonTerminal> 311 </RuleItem> 312 <RuleItem> 313 <Type>0</Type> 314 <Optional>0</Optional> 315 <Repetitive>0</Repetitive> 316 <AnyExcept>0</AnyExcept> 317 <Terminal>;</Terminal> 318 </RuleItem> 319 </SubItems> 320 </RuleItem> 321 <RuleItem> 285 322 <Type>0</Type> 286 323 <Optional>0</Optional> … … 1472 1509 <AnyExcept>0</AnyExcept> 1473 1510 <Terminal>-</Terminal> 1511 </RuleItem> 1512 <RuleItem> 1513 <Type>0</Type> 1514 <Optional>0</Optional> 1515 <Repetitive>0</Repetitive> 1516 <AnyExcept>0</AnyExcept> 1517 <Terminal>and</Terminal> 1518 </RuleItem> 1519 <RuleItem> 1520 <Type>0</Type> 1521 <Optional>0</Optional> 1522 <Repetitive>0</Repetitive> 1523 <AnyExcept>0</AnyExcept> 1524 <Terminal>or</Terminal> 1525 </RuleItem> 1526 <RuleItem> 1527 <Type>0</Type> 1528 <Optional>0</Optional> 1529 <Repetitive>0</Repetitive> 1530 <AnyExcept>0</AnyExcept> 1531 <Terminal>xor</Terminal> 1532 </RuleItem> 1533 <RuleItem> 1534 <Type>0</Type> 1535 <Optional>0</Optional> 1536 <Repetitive>0</Repetitive> 1537 <AnyExcept>0</AnyExcept> 1538 <Terminal>shl</Terminal> 1539 </RuleItem> 1540 <RuleItem> 1541 <Type>0</Type> 1542 <Optional>0</Optional> 1543 <Repetitive>0</Repetitive> 1544 <AnyExcept>0</AnyExcept> 1545 <Terminal>shr</Terminal> 1546 </RuleItem> 1547 <RuleItem> 1548 <Type>0</Type> 1549 <Optional>0</Optional> 1550 <Repetitive>0</Repetitive> 1551 <AnyExcept>0</AnyExcept> 1552 <Terminal>in</Terminal> 1553 </RuleItem> 1554 <RuleItem> 1555 <Type>0</Type> 1556 <Optional>0</Optional> 1557 <Repetitive>0</Repetitive> 1558 <AnyExcept>0</AnyExcept> 1559 <Terminal>as</Terminal> 1474 1560 </RuleItem> 1475 1561 </RuleItems> … … 1832 1918 </RuleItems> 1833 1919 </Rule> 1920 <Rule> 1921 <Name>CaseOfState</Name> 1922 <CreateSourceNode>0</CreateSourceNode> 1923 <RuleItems> 1924 <Type>0</Type> 1925 <RuleItem> 1926 <Type>1</Type> 1927 <Optional>0</Optional> 1928 <Repetitive>0</Repetitive> 1929 <AnyExcept>0</AnyExcept> 1930 <NonTerminal>Identifier</NonTerminal> 1931 </RuleItem> 1932 <RuleItem> 1933 <Type>0</Type> 1934 <Optional>0</Optional> 1935 <Repetitive>0</Repetitive> 1936 <AnyExcept>0</AnyExcept> 1937 <Terminal>:</Terminal> 1938 </RuleItem> 1939 <RuleItem> 1940 <Type>1</Type> 1941 <Optional>0</Optional> 1942 <Repetitive>0</Repetitive> 1943 <AnyExcept>0</AnyExcept> 1944 <NonTerminal>Statement</NonTerminal> 1945 </RuleItem> 1946 <RuleItem> 1947 <Type>0</Type> 1948 <Optional>0</Optional> 1949 <Repetitive>0</Repetitive> 1950 <AnyExcept>0</AnyExcept> 1951 <Terminal>;</Terminal> 1952 </RuleItem> 1953 </RuleItems> 1954 </Rule> 1834 1955 </Rules> 1835 1956 <TopRule>Program</TopRule>
Note:
See TracChangeset
for help on using the changeset viewer.