Class: Q_Parser
- Inherits:
-
Racc::Parser
- Object
- Racc::Parser
- Q_Parser
- Defined in:
- lib/q-language/parser.rb
Constant Summary collapse
- Racc_debug_parser =
false
- Racc_arg =
[ [2,9,6,7,2,10,6,7,2,3,12,13], [2,3,2,2,4,4,4,4,0,1,6,7], [-9,-9,-8,-9,-9,-2,-9,-5,-6,14,-1,-7,-3,-4], [6,9,-2,1,2,nil,5,5,nil,nil,nil,nil,nil,nil], [8,4,11,1], [3,2,3,1], [nil,5,nil,nil], [nil,3,-1,-2], 7, [0,0,:racc_error, 3,8,:new_block, 1,10,:block, 2,10,:new_variable, 2,10,:new_literal, 1,10,:new_method, 1,9,:new_node_array, 2,9,:append_node, 0,9,:new_empty_array], { false=>0, error: 1, "{"=>2, "}"=>3, ":"=>4, ID: 5, STRING: 6 }, 14, 9, true]
Instance Method Summary collapse
-
#initialize(script) ⇒ Q_Parser
constructor
A new instance of Q_Parser.
-
#next_token ⇒ Object
Removes and returns one item from the Array of script tokens.
-
#on_error ⇒ Object
Raises a SyntaxError.
-
#parse ⇒ Object
Parses the Q script, then returns an Array containing the outermost Node, an Array of every block Node, an Array of every literal Node, an Array of every method Node, and an Array of every variable Node.
-
#scan_literal ⇒ Object
Returns the string enclosed by the set of parentheses beginning at the ‘(’ exactly one character before the StringScanner’s current pointer location and ending at the ‘)’ character after all sets of parentheses have been balanced.
Constructor Details
#initialize(script) ⇒ Q_Parser
Returns a new instance of Q_Parser.
10 11 12 |
# File 'lib/q-language/parser.rb', line 10 def initialize (script) @ss = StringScanner.new(script) end |
Instance Method Details
#next_token ⇒ Object
Removes and returns one item from the Array of script tokens. Required by racc.
17 18 19 |
# File 'lib/q-language/parser.rb', line 17 def next_token @tokens.shift end |
#on_error ⇒ Object
Raises a SyntaxError. Required by racc.
24 25 26 |
# File 'lib/q-language/parser.rb', line 24 def on_error (*) raise SyntaxError, "tokens do not form valid script" end |
#parse ⇒ Object
Parses the Q script, then returns an Array containing the outermost Node, an Array of every block Node, an Array of every literal Node, an Array of every method Node, and an Array of every variable Node. If any invalid tokens are encountered in the script or if the tokens do not form a valid Q script, raises a SyntaxError.
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/q-language/parser.rb', line 34 def parse @tokens = [] @ss.reset until @ss.eos? @tokens << case c = @ss.getch when /\s/ then next when /[\p{alpha}_]/ @ss.unscan.scan /[\p{alnum}_]+[?!]?/ [:ID, @ss.matched.intern] when /[}:{]/ then [c, 0] when /\(/ then [:STRING, scan_literal] else raise SyntaxError, "script contains invalid token `#{c}'" end end @tokens << [false, false] @blocks = [] @literals = [] @methods = [] @variables = [] return do_parse, @blocks, @literals, @methods, @variables end |
#scan_literal ⇒ Object
Returns the string enclosed by the set of parentheses beginning at the ‘(’ exactly one character before the StringScanner’s current pointer location and ending at the ‘)’ character after all sets of parentheses have been balanced. Parenthesis characters escaped by a preceding ‘' are not considered in the balance count. If the end of the string is reached before the closing ’)‘ character, raises a SyntaxError.
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/q-language/parser.rb', line 67 def scan_literal strings = [] p_count = 0 while s = @ss.scan_until(/(?=[()\\])/) case (c = @ss.getch).ord when 41 then (p_count == 0) ? (return (strings << s).join) : (p_count -= 1) # ) when 40 then p_count += 1 # ( when 92 then %w[) (].include?(@ss.peek(1)) ? (strings << s << c << @ss.getch) : (next) # \ end strings << s << c end raise SyntaxError, "unterminated literal meets end of script" end |