Changeset 133 for branches/generator


Ignore:
Timestamp:
Dec 25, 2017, 12:23:39 PM (7 years ago)
Author:
chronos
Message:
  • Modified: Generate subitems as local function inside method.
Location:
branches/generator
Files:
2 added
2 edited

Legend:

Unmodified
Added
Removed
  • branches/generator/Grammers/Test Subitems.grm

    r132 r133  
    1313          <Repetitive>0</Repetitive>
    1414          <AnyExcept>0</AnyExcept>
    15           <Terminal>d</Terminal>
     15          <Terminal>a</Terminal>
    1616        </RuleItem>
    1717        <RuleItem>
    1818          <Type>2</Type>
    19           <Optional>-1</Optional>
     19          <Optional>0</Optional>
    2020          <Repetitive>0</Repetitive>
    2121          <AnyExcept>0</AnyExcept>
     
    2727              <Repetitive>0</Repetitive>
    2828              <AnyExcept>0</AnyExcept>
    29               <Terminal>a</Terminal>
     29              <Terminal>b</Terminal>
    3030            </RuleItem>
    3131            <RuleItem>
     
    3434              <Repetitive>0</Repetitive>
    3535              <AnyExcept>0</AnyExcept>
    36               <Terminal>b</Terminal>
     36              <Terminal>c</Terminal>
    3737            </RuleItem>
    3838          </SubItems>
     
    4343          <Repetitive>0</Repetitive>
    4444          <AnyExcept>0</AnyExcept>
    45           <Terminal>c</Terminal>
     45          <Terminal>d</Terminal>
    4646        </RuleItem>
    4747      </RuleItems>
  • branches/generator/UBuilder.pas

    r132 r133  
    1414  TBuilder = class
    1515  private
     16    LocalFunctions: string;
     17    LocalFunctionIndex: Integer;
    1618    function GetItemString(Item: TRuleItem; Required: Boolean; IndentLevel: Integer): string;
    1719    function StringText(Text: string): string;
    1820    procedure BuildMain(FileName: string);
    1921    procedure BuildParser(FileName: string);
    20     function BuildParserItems(Items: TRuleItems; IndentLevel: Integer): string;
     22    function BuildParserItems(Items: TRuleItems; Required: Boolean; IndentLevel: Integer): string;
    2123    procedure BuildSource(FileName: string);
    2224    procedure BuildTokenizer(FileName: string);
     
    4446      StringText(Item.TerminalTo) + ''', ' + BooleanText[Required] + ')';
    4547    ritSubItems: begin
    46       Result := DupeString('  ', IndentLevel) + 'begin' + LineEnding;
    47       Result := Result + BuildParserItems(Item.SubItems, IndentLevel + 1);
    48       Result := Result + DupeString('  ', IndentLevel) + 'end';
     48      LocalFunctions := LocalFunctions + 'function ParseSubitems' + IntToStr(LocalFunctionIndex) + '(Required: Boolean = False): Boolean;' + LineEnding;
     49      LocalFunctions := LocalFunctions + 'begin' + LineEnding;
     50      LocalFunctions := LocalFunctions + '  Result := True;' + LineEnding;
     51      LocalFunctions := LocalFunctions + BuildParserItems(Item.SubItems, Required, 1);
     52      LocalFunctions := LocalFunctions + 'end;' + LineEnding + LineEnding;
     53
     54      Result := Result + 'ParseSubitems' + IntToStr(LocalFunctionIndex) + '(' + BooleanText[Required] + ')';
     55      Inc(LocalFunctionIndex);
    4956    end;
    5057  end;
     
    6067  ParserFile: TStringList;
    6168  Rule: TRule;
     69  FunctionBody: string;
    6270begin
    6371  ParserFile := TStringList.Create;
     
    137145    Add('end;');
    138146    Add('');
     147    LocalFunctionIndex := 1;
     148    LocalFunctions := '';
    139149    for Rule in Grammer.Rules do
    140150    if Rule.Level = rlParser then begin
    141       Add('function TParser.Parse' + Rule.Name + '(Required: Boolean = False): Boolean;');
    142       Add('begin');
    143       Add('  Result := True;');
    144       Text := Text + BuildParserItems(Rule.Items, 1);
    145       Add('end;');
    146       Add('');
     151      FunctionBody := BuildParserItems(Rule.Items, True, 1);
     152      Text := Text + 'function TParser.Parse' + Rule.Name + '(Required: Boolean = False): Boolean;' + LineEnding;
     153      Text := Text + LocalFunctions;
     154      Text := Text + 'begin' + LineEnding;
     155      Text := Text + '  Result := True;' + LineEnding;
     156      Text := Text + FunctionBody;
     157      Text := Text + 'end;' + LineEnding + LineEnding;
    147158    end;
    148159    Add('');
     
    153164end;
    154165
    155 function TBuilder.BuildParserItems(Items: TRuleItems; IndentLevel: Integer): string;
     166function TBuilder.BuildParserItems(Items: TRuleItems; Required: Boolean; IndentLevel: Integer): string;
    156167var
    157168  I: Integer;
    158169  Item: TRuleItem;
    159   Required: Boolean;
     170  ItemRequired: Boolean;
    160171  Line: string;
    161172begin
     
    163174  I := 0;
    164175  for Item in Items do begin
    165     Required := not Item.Optional;
     176    ItemRequired := not Item.Optional and Required;
    166177    Line := '';
    167178    case Items.RuleType of
     
    173184      end;
    174185      rtAnd: begin
    175         if not Item.Optional and not (Item.RuleItemType = ritSubItems) then
     186        if not Item.Optional then
    176187          Line := Line + DupeString('  ', IndentLevel) + 'Result := Result and ';
    177188        if Item.Repetitive then begin
    178189          if not Item.Optional then
    179             Line := Line + DupeString('  ', IndentLevel) + GetItemString(Item, Required, IndentLevel) + ';' + LineEnding;
     190            Line := Line + DupeString('  ', IndentLevel) + GetItemString(Item, ItemRequired, IndentLevel) + ';' + LineEnding;
    180191          Line := Line + DupeString('  ', IndentLevel) + 'repeat' + LineEnding + DupeString('  ', IndentLevel) + 'if not ';
    181           Required := False;
     192          Inc(IndentLevel);
     193          ItemRequired := False;
    182194        end;
    183         Line := Line + GetItemString(Item, Required, IndentLevel);
    184         if Item.Repetitive then
     195        Line := Line + GetItemString(Item, ItemRequired, IndentLevel);
     196        if Item.Repetitive then begin
    185197          Line := Line + ' then Break;' + LineEnding +
    186198          DupeString('  ', IndentLevel) + 'until False';
     199          Dec(IndentLevel);
     200        end;
    187201        Line := Line + ';' + LineEnding +
    188202          DupeString('  ', IndentLevel) + 'if not Result then Exit;';
Note: See TracChangeset for help on using the changeset viewer.