lib/d-mark/parser.rb in d-mark-1.0.0a3 vs lib/d-mark/parser.rb in d-mark-1.0.0a4

- old
+ new

@@ -14,12 +14,12 @@ end attr_reader :pos def initialize(input) - @input = input - @input_chars = @input.chars + @input_chars = input.chars + @length = @input_chars.size @pos = 0 @col_nr = 0 @line_nr = 0 end @@ -46,34 +46,26 @@ res end ########## - def peek_char(pos = @pos) - if eof? - nil - else - @input_chars[pos] - end - end - def eof?(pos = @pos) - pos >= @input_chars.size + pos >= @length end def advance - if !eof? && @input_chars[@pos] == "\n" + if @input_chars[@pos] == "\n" @line_nr += 1 @col_nr = 0 end @pos += 1 @col_nr += 1 end def read_char(c) - char = peek_char + char = @input_chars[@pos] if char != c raise_parse_error("expected #{c.inspect}, but got #{char.nil? ? 'EOF' : char.inspect}") else advance char @@ -116,11 +108,11 @@ def try_read_blank_line pos = @pos loop do - case peek_char(pos) + case @input_chars[pos] when ' ' pos += 1 when nil break pos + 1 when "\n" @@ -131,12 +123,12 @@ end end # FIXME: ugly and duplicated def try_read_block_start - if peek_char == '#' - next_char = peek_char(@pos + 1) + if @input_chars[@pos] == '#' + next_char = @input_chars[@pos + 1] ('a'..'z').cover?(next_char) else false end end @@ -144,11 +136,11 @@ def detect_indentation indentation_chars = 0 pos = @pos loop do - case peek_char(pos) + case @input_chars[pos] when ' ' pos += 1 indentation_chars += 1 else break @@ -168,17 +160,17 @@ def read_single_block read_char('#') identifier = read_identifier attributes = - if peek_char == '[' + if @input_chars[@pos] == '[' read_attributes else {} end - case peek_char + case @input_chars[@pos] when nil, "\n" advance ElementNode.new(identifier, attributes, []) else read_char(' ') @@ -187,11 +179,11 @@ ElementNode.new(identifier, attributes, content) end end def read_end_of_inline_content - char = peek_char + char = @input_chars[@pos] case char when "\n", nil advance when '}' raise_parse_error('unexpected } -- try escaping it as "%}"') @@ -205,32 +197,30 @@ b = read_identifier_tail "#{a}#{b}" end def read_identifier_head - char = peek_char + char = @input_chars[@pos] case char - when 'a'..'z' + when 'a'..'z', 'A'..'Z' advance char else raise_parse_error("expected an identifier, but got #{char.inspect}") end end + IDENTIFIER_CHARS = Set.new(['a'..'z', 'A'..'Z', ['-', '_'], '0'..'9'].map(&:to_a).flatten) + def read_identifier_tail res = '' loop do - char = peek_char - case char - when 'a'..'z', '-', '0'..'9' - advance - res << char - else - break - end + char = @input_chars[@pos] + break unless IDENTIFIER_CHARS.include?(char) + advance + res << char end res.to_s end @@ -239,20 +229,20 @@ res = {} at_start = true loop do - char = peek_char + char = @input_chars[@pos] case char when ']' advance break else read_char(',') unless at_start key = read_attribute_key - if peek_char == '=' + if @input_chars[@pos] == '=' read_char('=') value = read_attribute_value else value = key end @@ -273,11 +263,11 @@ def read_attribute_value res = '' is_escaping = false loop do - char = peek_char + char = @input_chars[@pos] if is_escaping case char when '%', ']', ',' advance @@ -313,11 +303,11 @@ def read_inline_content res = [] loop do - char = peek_char + char = @input_chars[@pos] case char when "\n", nil break when '}' break @@ -334,39 +324,39 @@ def read_string res = '' loop do - char = peek_char + char = @input_chars[@pos] case char when nil, "\n", '%', '}' break else advance res << char end end - res.to_s + res end def read_percent_body - char = peek_char + char = @input_chars[@pos] case char when '%', '}', '#' advance - char.to_s + char when nil, "\n" raise_parse_error('expected something after %') else read_inline_element end end def read_inline_element name = read_identifier attributes = - if peek_char == '[' + if @input_chars[@pos] == '[' read_attributes else {} end read_char('{')