Ignore:
Timestamp:
Dec 26, 2017, 6:59:40 PM (7 years ago)
Author:
chronos
Message:
  • Added: Support for whitespaces in And rule.
  • Added: Terminals can be specified as escaped strings with slash.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/generator/UBuilder.pas

    r135 r136  
    1818    function Indent(Count: Integer): string;
    1919    function GetItemString(Item: TRuleItem; Required: Boolean; IndentLevel: Integer): string;
    20     function StringText(Text: string): string;
     20    function StringText(const Text: string; Escaped: Boolean): string;
    2121    procedure BuildMain(FileName: string);
    2222    procedure BuildParser(FileName: string);
     
    4646  case Item.RuleItemType of
    4747    ritTerminal: Result := 'Expect(''' +
    48       StringText(Item.Terminal) + ''', ' + BooleanText[Required] + ')';
    49     ritNonTerminal: Result := 'Parse' + Item.NonTerminal.Name + '(' + BooleanText[Required] + ')';
     48      StringText(Item.Terminal, Item.EscapedStrings) + ''', Required and ' + BooleanText[Required] + ')';
     49    ritNonTerminal: Result := 'Parse' + Item.NonTerminal.Name + '(Required and ' + BooleanText[Required] + ')';
    5050    ritTerminalRange: Result := 'ExpectRange(''' +
    51       StringText(Item.TerminalFrom) + ''', ''' +
    52       StringText(Item.TerminalTo) + ''', ' + BooleanText[Required] + ')';
     51      StringText(Item.TerminalFrom, Item.EscapedStrings) + ''', ''' +
     52      StringText(Item.TerminalTo, Item.EscapedStrings) + ''', Required and ' + BooleanText[Required] + ')';
    5353    ritSubItems: begin
    5454      LocalFunctions := LocalFunctions + 'function ParseSubitems' + IntToStr(LocalFunctionIndex) + '(Required: Boolean = False): Boolean;' + LineEnding;
    55       LocalFunctions := LocalFunctions + 'var' + LineEnding + '  OldPosition: Integer;' + LineEnding;
     55      LocalFunctions := LocalFunctions + 'var' + LineEnding;
     56      LocalFunctions := LocalFunctions + '  OldPosition: TPosition;' + LineEnding;
    5657      LocalFunctions := LocalFunctions + 'begin' + LineEnding;
    5758      LocalFunctions := LocalFunctions + '  Result := True;' + LineEnding;
     
    5960      LocalFunctions := LocalFunctions + 'end;' + LineEnding + LineEnding;
    6061
    61       Result := Result + 'ParseSubitems' + IntToStr(LocalFunctionIndex) + '(' + BooleanText[Required] + ')';
     62      Result := Result + 'ParseSubitems' + IntToStr(LocalFunctionIndex) + '(Required and ' + BooleanText[Required] + ')';
    6263      Inc(LocalFunctionIndex);
    6364    end;
     
    6566end;
    6667
    67 function TBuilder.StringText(Text: string): string;
    68 begin
    69   Result := StringReplace(Text, '''', '''''', [rfReplaceAll]);
     68function TBuilder.StringText(const Text: string; Escaped: Boolean): string;
     69begin
     70  Result := Text;
     71  Result := StringReplace(Result, '''', '''''', [rfReplaceAll]);
     72  if Escaped then begin
     73    Result := StringReplace(Result, '\n', '''#10''', [rfReplaceAll]);
     74    Result := StringReplace(Result, '\r', '''#13''', [rfReplaceAll]);
     75    Result := StringReplace(Result, '\t', '''#9''', [rfReplaceAll]);
     76    Result := StringReplace(Result, '\\', '\', [rfReplaceAll]);
     77  end;
    7078end;
    7179
     
    215223      end;
    216224      rtAnd: begin
     225        if Assigned(Items.Grammer.WhiteSpaceRule) and Items.WithWhiteSpeaces
     226        and (I > 0) then begin
     227          Line := Line + Indent(IndentLevel) + 'repeat' + LineEnding;
     228          Inc(IndentLevel);
     229          Line := Line + Indent(IndentLevel) + 'if not Parse' +
     230            Items.Grammer.WhiteSpaceRule.Name + '(False)' +
     231            ' then Break;' + LineEnding;
     232          Dec(IndentLevel);
     233          Line := Line + Indent(IndentLevel) + 'until False;' + LineEnding;
     234        end;
     235
    217236        if not Item.Optional then
    218237          Line := Line + Indent(IndentLevel) + 'Result := Result and ';
     
    245264    rtOr: begin
    246265      Result := Result + Indent(IndentLevel) + 'else begin' + LineEnding;
    247       Result := Result + Indent(IndentLevel) + '  Error(''Unexpected token'');' + LineEnding;
     266      Result := Result + Indent(IndentLevel) + '  if Required then Error(''Unexpected token'');' + LineEnding;
    248267      Result := Result + Indent(IndentLevel) + '  Result := False;' + LineEnding;
    249268      Result := Result + Indent(IndentLevel) + 'end;' + LineEnding;
     
    360379    for Item in Items do begin
    361380      case Item.RuleItemType of
    362         ritTerminal: Result := Result + '(Value = ''' + StringText(Item.Terminal) + ''')';
     381        ritTerminal: Result := Result + '(Value = ''' + StringText(Item.Terminal, Item.EscapedStrings) + ''')';
    363382        ritNonTerminal: Result := Result + 'Is' + Item.NonTerminalName + '(Value)';
    364         ritTerminalRange: Result := Result + '((Value > ''' + StringText(Item.TerminalFrom) + ''') and (Value < ''' + StringText(Item.TerminalTo) + '''))';
     383        ritTerminalRange: Result := Result + '((Value > ''' + StringText(Item.TerminalFrom, Item.EscapedStrings) + ''') and (Value < ''' + StringText(Item.TerminalTo, Item.EscapedStrings) + '''))';
    365384        ritSubItems: Result := Result + '(' + BuildTokenizerItems(SourceFile, Item.SubItems) + ')';
    366385      end;
Note: See TracChangeset for help on using the changeset viewer.