Class: CompactData::Tokeniser::Context
- Inherits:
-
Object
- Object
- CompactData::Tokeniser::Context
- Defined in:
- lib/compactdata/tokeniser/context.rb
Overview
A parsing context for a CompactData String
Constant Summary collapse
- WS =
" \t\r\n"
- INTEGER_REGEX =
'^-?(?:0|[1-9]\d*)$'
- FLOAT_REGEX =
'^-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?$'
- NON_STRING_TOKENS =
'[]();"=`'
Instance Method Summary collapse
- #escaped?(str, pos) ⇒ Boolean
-
#initialize(str) ⇒ Context
constructor
A new instance of Context.
- #next_token ⇒ Object
- #parse ⇒ Object
- #scan_to_end_of_quoted(str, start, quote_char) ⇒ Object
- #scan_to_end_of_string(str, start) ⇒ Object
Constructor Details
#initialize(str) ⇒ Context
Returns a new instance of Context.
12 13 14 15 16 |
# File 'lib/compactdata/tokeniser/context.rb', line 12 def initialize(str) @str = str @tokens = [] @tok_start = 0 end |
Instance Method Details
#escaped?(str, pos) ⇒ Boolean
112 113 114 |
# File 'lib/compactdata/tokeniser/context.rb', line 112 def escaped?(str, pos) pos >= 0 && (str[pos] == '~' || str[pos] == '\\') end |
#next_token ⇒ Object
24 25 26 27 28 29 30 31 32 33 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 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/compactdata/tokeniser/context.rb', line 24 def next_token while @tok_start < @str.length break unless WS.include?(@str[@tok_start]) @tok_start += 1 end return false if @tok_start >= @str.length case @str[@tok_start] when '(' tok_type = :lparen tok_end = @tok_start + 1 when ')' tok_type = :rparen tok_end = @tok_start + 1 when '[' tok_type = :lbracket tok_end = @tok_start + 1 when ']' tok_type = :rbracket tok_end = @tok_start + 1 when ';' tok_type = :struct_sep tok_end = @tok_start + 1 when '=' tok_type = :equals tok_end = @tok_start + 1 when '"' tok_type = :quoted tok_end = scan_to_end_of_quoted(@str, @tok_start, '"') when '`' tok_type = :quoted tok_end = scan_to_end_of_quoted(@str, @tok_start, '`') when '{' ## Braced strings must include the braces in the string tok_type = :quoted tok_end = scan_to_end_of_quoted(@str, @tok_start, '}') else tok_type = :string tok_end = scan_to_end_of_string(@str, @tok_start) end tok_value = @str[@tok_start..(tok_end - 1)].strip if tok_value.match? INTEGER_REGEX number = tok_value.to_i @tokens.push Token.new(:integer, number, @tok_start, tok_end) elsif tok_value.match? FLOAT_REGEX number = tok_value.to_f @tokens.push Token.new(:float, number, @tok_start, tok_end) elsif tok_value == 'null' @tokens.push Token.new(:null, nil, @tok_start, tok_end) elsif tok_value == 'true' @tokens.push Token.new(true, true, @tok_start, tok_end) elsif tok_value == 'false' @tokens.push Token.new(false, false, @tok_start, tok_end) else @tokens.push Token.new(tok_type, tok_value, @tok_start, tok_end) end @tok_start = tok_end tok_end < @str.length end |
#parse ⇒ Object
18 19 20 21 22 |
# File 'lib/compactdata/tokeniser/context.rb', line 18 def parse while next_token end @tokens end |
#scan_to_end_of_quoted(str, start, quote_char) ⇒ Object
89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/compactdata/tokeniser/context.rb', line 89 def scan_to_end_of_quoted(str, start, quote_char) end_str = start + 1 while end_str < str.length end_char = str[end_str] prev_char = str[end_str - 1] break if end_char == quote_char && prev_char != '\\' && prev_char != '~' end_str += 1 end end_str + 1 end |
#scan_to_end_of_string(str, start) ⇒ Object
102 103 104 105 106 107 108 109 110 |
# File 'lib/compactdata/tokeniser/context.rb', line 102 def scan_to_end_of_string(str, start) end_str = start + 1 while end_str < str.length break if NON_STRING_TOKENS.include?(str[end_str]) && !escaped?(str, end_str - 1) end_str += 1 end end_str end |