+ if txt.chars[0] == delimiter_start and txt.chars[3] == '\n' then behead = 4 # ignore first \n in """
+ end
+ return txt.substring(behead, txt.length - behead - betail)
+ end
+
+ redef fun accept_literal(v) do
+ value = raw_text
+ bytes = raw_text.to_bytes
+ end
+end
+
+redef class AEndStringExpr
+ redef var delimiter_end is lazy do return '"'
+ redef fun prefix do return ""
+end
+
+redef class AStartStringExpr
+ redef var delimiter_start is lazy do
+ var str = n_string.text
+ for i in [0 .. str.length[ do
+ var c = str[i]
+ if c == '"' or c == '\'' then
+ return c
+ end
+ end
+ # Cannot happen, unless the parser is bugged
+ abort
+ end
+
+ redef fun suffix do return ""
+end
+
+redef class AMidStringExpr
+ redef fun prefix do return ""
+ redef fun suffix do return ""
+end
+
+redef class AStringExpr
+ redef var delimiter_start is lazy do
+ var str = text
+ for i in [0 .. str.length[ do
+ var c = str[i]
+ if c == '"' or c == '\'' then
+ delimiter_end = c
+ return c
+ end
+ end
+ # Cannot happen, unless the parser is bugged
+ abort
+ end
+
+ redef var delimiter_end is lazy do return delimiter_start
+
+ redef fun accept_literal(v)
+ do
+ super
+ if not is_valid_augmentation then
+ v.toolcontext.error(hot_location, "Error: invalid prefix/suffix combination {prefix}/{suffix}")
+ return
+ end
+ if prefix != "raw" then
+ bytes = raw_text.unescape_to_bytes
+ value = bytes.to_s
+ end
+ end
+end
+
+redef class ASuperstringExpr
+ super AugmentedStringFormExpr
+
+ redef var prefix is lazy do
+ var fst = n_exprs.first
+ if fst isa AugmentedStringFormExpr then
+ var prf = fst.prefix
+ delimiter_start = fst.delimiter_start
+ delimiter_end = delimiter_start
+ return prf
+ end
+ return ""
+ end
+
+ redef var suffix is lazy do
+ var lst = n_exprs.last
+ # Forces the system to update the delimiter's value
+ prefix
+ if lst isa AugmentedStringFormExpr then
+ lst.delimiter_end = delimiter_start
+ return lst.suffix
+ end
+ return ""
+ end
+
+ redef fun accept_literal(v)
+ do
+ if is_bytestring then
+ v.toolcontext.error(hot_location, "Error: cannot produce a ByteString on a Superstring")
+ return
+ end
+ if not is_valid_augmentation then
+ v.toolcontext.error(hot_location, "Error: invalid prefix/suffix combination {prefix}/{suffix}")
+ return
+ end
+ end
+
+ redef fun visit_all(v) do
+ super
+ if prefix != "raw" then
+ for i in n_exprs do
+ if not i isa AStringFormExpr then continue
+ i.bytes = i.raw_text.unescape_to_bytes
+ i.value = i.bytes.to_s
+ end