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('{')