╭─────────────╮ │scroll to top│ ╰─────────────╯ ╭ gen_parser_oracle.zig ────────────────────────────────────────╮ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────────────────────╯
╭ find file ─ ─ ─ ─ ─ ─ ─ ─ ─ ─╮ ╭────╮ ╭ clone ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╮ │ │ │http│ ssh │ │ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─╯ ╰────╯ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╯
660 } 661 662 // AND <- '&' Spacing 663 fn eatAnd(p: *Parser) bool { 664 return p.eat('&') and p.eatSpacing(); 665 } 666 667 // NOT <- '!' Spacing 668 fn eatNot(p: *Parser) bool { 669 return p.eat('!') and p.eatSpacing(); 670 } 671 672 // QUERY <- '?' Spacing 673 fn eatQuery(p: *Parser) bool { 674 return p.eat('?') and p.eatSpacing(); 675 } 676 677 // STAR <- '*' Spacing 678 fn eatStar(p: *Parser) bool { 679 return p.eat('*') and p.eatSpacing(); 680 } 681 682 // PLUS <- '+' Spacing 683 fn eatPlus(p: *Parser) bool { 684 return p.eat('+') and p.eatSpacing(); 685 } 686 687 // OPEN <- '(' Spacing 688 fn eatOpen(p: *Parser) bool { 689 return p.eat('(') and p.eatSpacing(); 690 } 691 692 // CLOSE <- ')' Spacing 693 fn eatClose(p: *Parser) bool { 694 return p.eat(')') and p.eatSpacing(); 695 } 696 697 // DOT <- '.' Spacing 698 fn eatDot(p: *Parser) bool { 699 return p.eat('.') and p.eatSpacing(); 700 } 701 702 // Spacing <- ( Space / Comment )* 703 fn eatSpacing(p: *Parser) bool { 704 while (p.eatSpace() or p.eatComment()) {} 705 return true; 706 } 707 708 // Comment <- '#' ( !EndOfLine . )* EndOfLine 709 fn eatComment(p: *Parser) bool { 710 if (!p.eat('#')) return false; 711 while (!p.eatEndOfLine()) p.i += 1; 712 return true; 713 } 714 715 // Space <- ' ' / '\t' / EndOfLine 716 fn eatSpace(p: *Parser) bool { 717 return p.eat(' ') or p.eat('\t') or p.eatEndOfLine(); 718 } 719 720 // EndOfLine <- '\r\n' / '\n' / '\r' 721 fn eatEndOfLine(p: *Parser) bool { 722 return p.eat('\r') | p.eat('\n'); 723 } 724 725 fn peek(p: *Parser) ?u8 { 726 if (p.i < p.source.len) { 727 return p.source[p.i]; 728 } 729 return null; 730 } 731 732 fn next(p: *Parser) ?u8 { 733 if (p.i < p.source.len) { 734 defer p.i += 1; 735 return p.source[p.i]; 736 } 737 return null; 738 } 739 740 fn eat(p: *Parser, byte: u8) bool { 741 if (p.i < p.source.len and p.source[p.i] == byte) { 742 p.i += 1; 743 return true; 744 } 745 return false; 746 } 747 748 fn addNode(p: *Parser, node: Node) !Node.Index { 749 try p.nodes.append(p.gpa, node); 750 return @fromBackingInt(@intCast(p.nodes.items.len - 1)); 751 } 752 753 fn addExtra(p: *Parser, nodes: []const Node.Index) !Node.Slice { 754 const off = p.extra.items.len; 755 try p.extra.appendSlice(p.gpa, nodes); 756 return .{ .off = @intCast(off), .len = @intCast(p.extra.items.len - off) }; 757 } 758 759 const Pos = struct { 760 i: u32, 761 nodes_len: u32, 762 extra_len: u32, 763 strings_len: u32, 764 }; 765 766 fn savePos(p: *const Parser) Pos { 767 return .{ 768 .i = p.i, 769 .nodes_len = @intCast(p.nodes.items.len), 770 .extra_len = @intCast(p.extra.items.len), 771 .strings_len = @intCast(p.strings.items.len), 772 }; 773 } 774 775 fn restorePos(p: *Parser, pos: Pos) void { 776 assert(p.i >= pos.i); 777 p.i = pos.i; 778 p.nodes.shrinkRetainingCapacity(pos.nodes_len); 779 p.extra.shrinkRetainingCapacity(pos.extra_len); 780 p.strings.shrinkRetainingCapacity(pos.strings_len); 781 } 782 783 fn getExtra(p: *const Parser, s: Node.Slice) []const Node.Index { 784 return p.extra.items[s.off..][0..s.len]; 785 } 786 }; 787