Module: CommandSearch::Parser
- Defined in:
- lib/command_search/parser.rb
Class Method Summary collapse
- .clean!(ast) ⇒ Object
- .cluster_cmds!(ast) ⇒ Object
- .cluster_not!(ast) ⇒ Object
- .cluster_or!(ast) ⇒ Object
- .group_parens!(ast) ⇒ Object
- .l_merge!(ast, i) ⇒ Object
- .parse!(ast) ⇒ Object
- .r_merge!(ast, i) ⇒ Object
- .unchain!(ast) ⇒ Object
Class Method Details
.clean!(ast) ⇒ Object
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/command_search/parser.rb', line 104 def clean!(ast) return unless ast.any? if ast[0][:type] == :colon || ast[0][:type] == :compare r_merge!(ast, 0) end if ast[-1][:type] == :colon || ast[-1][:type] == :compare l_merge!(ast, ast.length - 1) end i = 1 while i < ast.length - 1 next i += 1 unless ast[i][:type] == :colon || ast[i][:type] == :compare if ast[i + 1][:type] == :minus r_merge!(ast, i + 1) elsif ![:str, :number, :quote].include?(ast[i - 1][:type]) r_merge!(ast, i) elsif ![:str, :number, :quote].include?(ast[i + 1][:type]) l_merge!(ast, i) else i += 1 end end end |
.cluster_cmds!(ast) ⇒ Object
29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/command_search/parser.rb', line 29 def cluster_cmds!(ast) i = 1 while i < ast.length - 1 type = ast[i][:type] next i += 1 unless type == :colon || type == :compare ast[(i - 1)..(i + 1)] = { type: type, nest_op: ast[i][:value], value: [ast[i - 1], ast[i + 1]] } end end |
.cluster_not!(ast) ⇒ Object
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/command_search/parser.rb', line 61 def cluster_not!(ast) i = ast.length while i > 0 i -= 1 type = ast[i][:type] cluster_not!(ast[i][:value]) if type == :and next unless type == :minus if i == ast.length - 1 ast.delete_at(i) next end ast[i][:type] = :not ast[i][:value] = [ast[i + 1]] ast.delete_at(i + 1) end end |
.cluster_or!(ast) ⇒ Object
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/command_search/parser.rb', line 42 def cluster_or!(ast) i = 0 while i < ast.length type = ast[i][:type] cluster_or!(ast[i][:value]) if type == :and || type == :not next i += 1 unless type == :pipe if i == 0 || i == ast.length - 1 ast.delete_at(i) next end val = [ast[i - 1], ast[i + 1]] cluster_or!(val) ast[i][:type] = :or ast[i][:value] = val ast.delete_at(i + 1) ast.delete_at(i - 1) end end |
.group_parens!(ast) ⇒ Object
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
# File 'lib/command_search/parser.rb', line 5 def group_parens!(ast) i = 0 opening_idxs = [] while i < ast.length next i += 1 unless ast[i][:type] == :paren if ast[i][:value] == '(' opening_idxs.push(i) ast.delete_at(i) next end ast.delete_at(i) opening = opening_idxs.pop() next unless opening val = ast.slice(opening, i - opening) if val.count > 1 ast[opening..(i - 1)] = { type: :and, value: val } i -= val.length next elsif val.count == 1 ast[opening] = val.first end end end |
.l_merge!(ast, i) ⇒ Object
97 98 99 100 101 102 |
# File 'lib/command_search/parser.rb', line 97 def l_merge!(ast, i) ast[i][:type] = :str return unless ast[i - 1] && ast[i - 1][:type] == :str ast[i][:value] = ast[i - 1][:value] + ast[i][:value] ast.delete_at(i - 1) end |
.parse!(ast) ⇒ Object
127 128 129 130 131 132 133 134 135 |
# File 'lib/command_search/parser.rb', line 127 def parse!(ast) clean!(ast) unchain!(ast) cluster_cmds!(ast) group_parens!(ast) cluster_not!(ast) cluster_or!(ast) ast end |
.r_merge!(ast, i) ⇒ Object
90 91 92 93 94 95 |
# File 'lib/command_search/parser.rb', line 90 def r_merge!(ast, i) ast[i][:type] = :str return unless ast[i + 1] && ast[i + 1][:type] == :str ast[i][:value] = ast[i][:value] + ast[i + 1][:value] ast.delete_at(i + 1) end |
.unchain!(ast) ⇒ Object
78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/command_search/parser.rb', line 78 def unchain!(ast) i = 1 while i < ast.length - 3 left = ast[i][:type] right = ast[i + 2][:type] i += 1 next unless left == :colon || left == :compare next unless right == :colon || right == :compare ast.insert(i, ast[i].clone()) end end |