From 97e33c576ae9c5db63a0e3c99a0b901a4323f965 Mon Sep 17 00:00:00 2001 From: Philippe Pittoli Date: Mon, 1 Mar 2021 16:13:22 +0100 Subject: [PATCH] Multi-lines + exceptions give the erroneous line. --- shard.yml | 2 +- src/specparser.cr | 46 ++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 41 insertions(+), 7 deletions(-) diff --git a/shard.yml b/shard.yml index 7af8979..bda050a 100644 --- a/shard.yml +++ b/shard.yml @@ -1,5 +1,5 @@ name: specparser -version: 0.5.0 +version: 0.5.1 authors: - Philippe Pittoli diff --git a/src/specparser.cr b/src/specparser.cr index cf4e073..e837ee6 100644 --- a/src/specparser.cr +++ b/src/specparser.cr @@ -81,13 +81,14 @@ class SpecParser property assignments : Hash(String, StringContainer | LongStringContainer | ArrayContainer) property sections : Array(Section) + property current_line_number = 0 def initialize @assignments = Hash(String, StringContainer | LongStringContainer | ArrayContainer).new @sections = Array(Section).new end - def parse_assignment (line : String) + def parse_assignment (line : String, content : Array(String)) # puts "simple assignment: #{line}" name = /([a-zA-Z][a-zA-Z0-9-_]*):/.match(line).try &.[1] @@ -100,6 +101,9 @@ class SpecParser return end + # In case the content is over several lines. + value = grab_content content, value + @assignments[name] = StringContainer.new value.lstrip(" ").rstrip(" ") end @@ -110,14 +114,17 @@ class SpecParser list = Array(String).new while line = content.shift? + @current_line_number += 1 case line when /^[ \t]*(#.*)?$/ # puts "blank line or comment, still in a list" when /^[ \t]+-([^#]*)/ # puts "line content: #{$~[1]}" - list.push $~[1].lstrip(" ").rstrip(" ") + current_line = $~[1].lstrip(" ") + list.push grab_content(content, current_line) else content.unshift line + @current_line_number -= 1 break end end @@ -138,6 +145,7 @@ class SpecParser value = String.build do |str| while line = content.shift? + @current_line_number += 1 case line when /^[ \t]*(#.*)?$/ # puts "blank line or comment, still in a code block" @@ -148,6 +156,7 @@ class SpecParser str << "#{$~[1]}\n" else content.unshift line + @current_line_number -= 1 break end end @@ -178,6 +187,7 @@ class SpecParser end while line = content.shift? + @current_line_number += 1 case line when /^[ \t]*#.*$/ # puts "blank line or comment, still in a section" @@ -194,6 +204,7 @@ class SpecParser codeblockvalue = String.build do |str| while line = content.shift? + @current_line_number += 1 case line when /^[ \t]*#.*?$/ # puts "blank line or comment, still in a free text in a section" @@ -202,6 +213,7 @@ class SpecParser str << "#{$~[1]}\n" else content.unshift line + @current_line_number -= 1 break end end @@ -216,6 +228,7 @@ class SpecParser list = Array(String).new while line = content.shift? + @current_line_number += 1 case line when /^[ \t]*#.*?$/ # puts "blank line or comment, still in a list in a section" @@ -225,6 +238,7 @@ class SpecParser list.push lcontent else content.unshift line + @current_line_number -= 1 break end end @@ -236,6 +250,7 @@ class SpecParser section.content[lname] = ArrayContainer.new list else content.unshift line + @current_line_number -= 1 break end end @@ -243,13 +258,32 @@ class SpecParser sections.push section end + # Remove \n when line ends with a backslash. + def grab_content(content : Array(String), current_value : String) + while current_value =~ /\\$/ + # Remove trailing backslash + current_value = current_value.rstrip "\\" + nl = content.shift? + if nl + @current_line_number += 1 + current_value += nl.lstrip + else + raise Exception.new "last line is ending with a backslash" + end + end + + current_value + end + def parse_lines(content : Array(String)) while line = content.shift? + @current_line_number += 1 + case line when /^[a-zA-Z][a-zA-Z0-9-_]*:[ \t]*([#].*)?$/ - parse_list line, content + parse_list line, content when /^[a-zA-Z][a-zA-Z0-9-_]*:[ \t]+[^#]+/ - parse_assignment line + parse_assignment line, content when /^[@][a-zA-Z][a-zA-Z0-9-_]*[ \t]*([#].*)?/ parse_code_block line, content when /^[%][a-zA-Z][a-zA-Z0-9-_]*[ \t]*([#].*)?/ @@ -259,7 +293,7 @@ class SpecParser when /^[ \t]+$/ # puts "empty line" when /^[ \t]+[^ \t#]/ - raise "line starting with spaces or a tabulation outside a list or a section: should not happen" + raise Exception.new "line #{@current_line_number}: line starting with spaces or a tabulation outside a list or a section: should not happen" end end end @@ -393,6 +427,6 @@ class SpecParser specs rescue e - raise Exception.new "unexpected parser error: #{e}" + raise Exception.new "unexpected parser error: #{e}, current line #{specs.not_nil!.current_line_number}" end end