[Checkins] SVN: Sandbox/malthe/Chameleon/src/chameleon/core/ Added interpolation parsing module (as a utility for concrete language implementations).

Malthe Borch mborch at gmail.com
Mon Sep 22 12:01:59 EDT 2008


Log message for revision 91348:
  Added interpolation parsing module (as a utility for concrete language implementations).

Changed:
  A   Sandbox/malthe/Chameleon/src/chameleon/core/parsing.py
  U   Sandbox/malthe/Chameleon/src/chameleon/core/tests/test_doctests.py

-=-
Added: Sandbox/malthe/Chameleon/src/chameleon/core/parsing.py
===================================================================
--- Sandbox/malthe/Chameleon/src/chameleon/core/parsing.py	                        (rev 0)
+++ Sandbox/malthe/Chameleon/src/chameleon/core/parsing.py	2008-09-22 16:01:58 UTC (rev 91348)
@@ -0,0 +1,127 @@
+import re
+import types
+
+re_interpolation = re.compile(
+    r'(?P<prefix>[^\\]\$|^\$)({((?P<expression>.*)})?|'
+    '(?P<variable>[A-Za-z][A-Za-z0-9_]*))')
+
+def interpolate(string, translator):
+    """Splits up an interpolation string expression on the form
+    ${<expression>} into a ``join`` expression.
+    
+    >>> def translator(string):
+    ...     return types.value(string)
+
+    >>> interpolate("${abc}", translator)
+    (value('abc'),)
+
+    >>> interpolate(" ${abc}", translator)
+    (' ', value('abc'))
+
+    >>> interpolate("abc${def}", translator)
+    ('abc', value('def'))
+
+    >>> interpolate("${def}abc", translator)
+    (value('def'), 'abc')
+
+    >>> interpolate("abc${def}ghi", translator)
+    ('abc', value('def'), 'ghi')
+
+    >>> interpolate("abc${def}ghi${jkl}", translator)
+    ('abc', value('def'), 'ghi', value('jkl'))
+
+    >>> interpolate("abc${def}", translator)
+    ('abc', value('def'))
+
+    >>> print interpolate(u"abc${ghi}", translator)
+    (u'abc', value('ghi'))
+        
+    """
+
+    m = match_interpolate(string, translator)
+    if m is None:
+        return (string,)
+
+    prefix = m.group('prefix')
+    parts = []
+
+    start = m.start() + len(prefix) - 1
+    if start > 0:
+        text = string[:start]
+        parts.append(text)
+
+    expression = m.group('expression')
+    variable = m.group('variable')
+
+    if expression:
+        parts.append(translator(expression))
+    elif variable:
+        parts.append(translator(variable))
+
+    rest = string[m.end():]
+    if len(rest):
+        parts.extend(interpolate(rest, translator))
+
+    return tuple(parts)
+
+def match_interpolate(string, translator):
+    """Search for an interpolation and return a match.
+
+    >>> def translator(string):
+    ...     return types.value(string)
+
+    >>> match_interpolate('${abc}', translator).group('expression')
+    'abc'
+
+    >>> match_interpolate(' ${abc}', translator).group('expression')
+    'abc'
+
+    >>> match_interpolate('abc${def}', translator).group('expression')
+    'def'
+
+    >>> match_interpolate('abc${def}ghi${jkl}', translator).group('expression')
+    'def'
+
+    >>> match_interpolate('$abc', translator).group('variable')
+    'abc'
+
+    >>> match_interpolate('${abc', translator)
+    Traceback (most recent call last):
+      ...
+    SyntaxError: Interpolation expressions must be of the form ${<expression>} (${abc)
+
+    """
+
+    m = re_interpolation.search(string)
+    if m is None:
+        return None
+
+    expression = m.group('expression')
+    variable = m.group('variable')
+
+    if expression:
+        left = m.start()+len(m.group('prefix'))+1
+        right = string.find('}')
+
+        while right != -1:
+            match = string[left:right]
+            try:
+                exp = translator(match)
+                break
+            except SyntaxError:
+                right = string.find('}', right)
+        else:
+            raise
+
+        string = string[:right+1]
+        return re_interpolation.search(string)
+
+    if m is None or (expression is None and variable is None):
+        raise SyntaxError(
+            "Interpolation expressions must be of the "
+            "form ${<expression>} (%s)" % string)
+
+    if expression and not m.group('expression'):
+        raise SyntaxError(expression)
+
+    return m

Modified: Sandbox/malthe/Chameleon/src/chameleon/core/tests/test_doctests.py
===================================================================
--- Sandbox/malthe/Chameleon/src/chameleon/core/tests/test_doctests.py	2008-09-22 16:01:31 UTC (rev 91347)
+++ Sandbox/malthe/Chameleon/src/chameleon/core/tests/test_doctests.py	2008-09-22 16:01:58 UTC (rev 91348)
@@ -13,7 +13,7 @@
     
 def test_suite():
     filesuites = 'template.txt', 'codegen.txt', 'translation.txt'
-    testsuites = 'translation', 'clauses'
+    testsuites = 'translation', 'clauses', 'parsing'
 
     chameleon.core.config.DISK_CACHE = False
     



More information about the Checkins mailing list