def flatten_template(cls, tree, text): """ Flattens a string template into concatenation """ # the previously seen character (n-1) preceding_slash = False # indicates whether we're inside of a string template inside_interpolation = False inside_unicode = UnicodeNameDecodeState.No buf = '' for c in text: if preceding_slash: if c == '{' or c == '}' or c == "\'" or c == '"': # custom escapes buf = f'{buf[:-1]}{c}' else: # avoid deprecation messages for invalid escape sequences if c == ' ': buf += '\\' if c == 'N': # start unicode escaped name sequence inside_unicode = UnicodeNameDecodeState.Start buf += c preceding_slash = False else: if inside_unicode != UnicodeNameDecodeState.No: if c == '{': inside_unicode = UnicodeNameDecodeState.Running tree.expect( inside_unicode == UnicodeNameDecodeState.Running, 'string_templates_nested') if c == '}': inside_unicode = UnicodeNameDecodeState.No buf += c elif inside_interpolation: if c == '}': # end string interpolation inside_interpolation = False tree.expect(len(buf) > 0, 'string_templates_empty') yield { '$OBJECT': 'code', 'code': unicode_escape(tree, buf) } buf = '' else: tree.expect(c != '{', 'string_templates_nested') buf += c elif c == '{': # string interpolation might be the start of the string. # example: "{..}" if len(buf) > 0: yield {'$OBJECT': 'string', 'string': buf} buf = '' inside_interpolation = True elif c == '}': tree.expect(0, 'string_templates_unopened') else: buf += c preceding_slash = c == '\\' # emit remaining string in the buffer tree.expect(not inside_interpolation, 'string_templates_unclosed') if len(buf) > 0: yield {'$OBJECT': 'string', 'string': buf}
def string(self, tree): """ Compiles a string tree. """ value = unicode_escape(tree, tree.child(0).value) return {'$OBJECT': 'string', 'string': value}
def flatten_template(cls, tree, text): """ Flattens a string template into concatenation """ # the previously seen character (n-1) preceding_slash = False # indicates whether we're inside of a string template inside_interpolation = False inside_unicode = UnicodeNameDecodeState.No buf = "" for c in text: if preceding_slash: if c == "{" or c == "}" or c == "'" or c == '"': # custom escapes buf = f"{buf[:-1]}{c}" else: # avoid deprecation messages for invalid escape sequences if c == " ": buf += "\\" if c == "N": # start unicode escaped name sequence inside_unicode = UnicodeNameDecodeState.Start buf += c preceding_slash = False else: if inside_unicode != UnicodeNameDecodeState.No: if c == "{": inside_unicode = UnicodeNameDecodeState.Running tree.expect( inside_unicode == UnicodeNameDecodeState.Running, "string_templates_nested", ) if c == "}": inside_unicode = UnicodeNameDecodeState.No buf += c elif inside_interpolation: if c == "}": # end string interpolation inside_interpolation = False tree.expect(len(buf) > 0, "string_templates_empty") yield { "$OBJECT": "code", "code": unicode_escape(tree, buf), } buf = "" else: tree.expect(c != "{", "string_templates_nested") buf += c elif c == "{": # string interpolation might be the start of the string. # example: "{..}" if len(buf) > 0: yield {"$OBJECT": "string", "string": buf} buf = "" inside_interpolation = True elif c == "}": tree.expect(0, "string_templates_unopened") else: buf += c preceding_slash = c == "\\" # emit remaining string in the buffer tree.expect(not inside_interpolation, "string_templates_unclosed") if len(buf) > 0: yield {"$OBJECT": "string", "string": buf}
def string(self, tree): """ Compiles a string tree. """ value = unicode_escape(tree, tree.child(0).value) return f'"{value}"'
def string(self, tree): """ Compiles a string tree. """ value = unicode_escape(tree, tree.child(0).value) return {"$OBJECT": "string", "string": value}