...
authorVolker Birk <vb@pep-project.org>
Fri, 25 Jan 2019 23:31:57 +0100
changeset 25 cb4a7f8b230d
parent 24 1cb8f7566a07
...
backend.py
pyPEG.py
samples/adressliste.yml2
samples/gen_addr_html.ysl2
yml2.py
yml2c
yml2proc
--- a/backend.py	Tue Nov 20 22:35:38 2018 +0100
+++ b/backend.py	Fri Jan 25 23:31:57 2019 +0100
@@ -4,17 +4,17 @@
 
 import re, codecs
 import fileinput
-import sys, traceback, exceptions, os
+import sys, traceback, os
 from xml.sax.saxutils import escape, quoteattr
 from copy import deepcopy
 from glob import glob
-from pyPEG import code, parse, parseLine, u, Symbol
+from pyPEG import code, parse, parseLine, Symbol
 from yml2 import ymlCStyle, comment, _inner
 
 ymlFunc, pointers, pythonFunc = {}, {}, {}
-in_ns = u""
+in_ns = ""
 operator = []
-included = u""
+included = ""
 includePath = []
 emitlinenumbers = False
 encoding = "utf-8"
@@ -29,9 +29,9 @@
 def clearAll():
     global ymlFunc, pointers, pythonFunc, in_ns, operator, included
     ymlFunc, pointers, pythonFunc = {}, {}, {}
-    in_ns = u""
+    in_ns = ""
     operator = []
-    included = u""
+    included = ""
 
 lq = re.compile(r"\|(\>*)(.*)")
 sq = re.compile(r"(\d*)\>(.*)")
@@ -45,82 +45,82 @@
 
 def pointer(name):
     try:
-        return u(pointers[name[1:]])
+        return pointers[name[1:]]
     except:
         if name == "*_trace_info":
-            return u'""'
+            return '""'
         if included:
-            raise LookupError(u"in " + included + u":" + u(line) + u": pointer " + name)
-        else:
-            raise LookupError(u"in " + u(line) + u": pointer " + name)
+            raise LookupError("in " + included + ":" + line + ": pointer " + name)
+        else:
+            raise LookupError("in " + line + ": pointer " + name)
 
 def evalPython(expr):
     try:
-        result = eval(u(expr), pythonFunc)
+        result = eval(expr, pythonFunc)
         if type(result) is str:
             return codecs.decode(result, encoding)
         else:
             return result
     except:
         name, parm, tb = sys.exc_info()
-        msg = u"in python expression: " + u(parm)
+        msg = "in python expression: " + parm
         if name is exceptions.SyntaxError:
             tbl = traceback.format_exception(name, parm, tb)
-            msg += u"\n" + tbl[-3] + tbl[-2]
-        else:
-            msg += u": " + expr + u"\n"
+            msg += "\n" + tbl[-3] + tbl[-2]
+        else:
+            msg += ": " + expr + "\n"
         if included:
-            raise name(u"in " + included + u":" + u(line) + u": " + msg)
-        else:
-            raise name(u"in " + u(line) + u": " + msg)
+            raise name("in " + included + ":" + line + ": " + msg)
+        else:
+            raise name("in " + line + ": " + msg)
     
 def execPython(script):
     try:
-        if type(script) is unicode:
-            exec script in pythonFunc
-        else:
-            exec codecs.decode(script, encoding) in pythonFunc
+        if type(script) is str:
+            exec(script, pythonFunc)
+        else:
+            exec(codecs.decode(script, encoding), pythonFunc)
     except:
         name, parm, tb = sys.exc_info()
-        msg = u"in python script: " + u(parm)
+        msg = "in python script: " + parm
         if name is exceptions.SyntaxError:
             tbl = traceback.format_exception(name, parm, tb)
-            msg += u"\n" + tbl[-3] + tbl[-2]
-        else:
-            msg += u": " + expr + u"\n"
+            msg += "\n" + tbl[-3] + tbl[-2]
+        else:
+            msg += ": " + expr + "\n"
         if included:
-            raise name(u"in " + included + u":" + u(line) + u": " + msg)
-        else:
-            raise name(u"in " + u(line) + u": " + msg)
+            raise name("in " + included + ":" + line + ": " + msg)
+        else:
+            raise name("in " + line + ": " + msg)
 
 def textOut(text):
     if not text:
-        return u""
-    if type(text) is not unicode:
+        return ""
+    if type(text) is not str:
         text = codecs.decode(text, encoding)
     text = text.replace(r'\"', r'\\"')
-    text = u'u"""' + text.replace('"', r'\"') + u'"""'
+    text = '"""' + text.replace('"', r'\"') + '"""'
     try:
         textFunc = ymlFunc["text"]
         parms = ['text', ('parm', [text])]
         c, result = textFunc(parms)
         if c:
-            if type(textFunc.alias) is unicode:
-                result += u"</" + textFunc.alias + u">"
-            else:
-                result += u"</" + codecs.decode(textFunc.alias, encoding) + u">"
+            if type(textFunc.alias) is str:
+                result += "</" + textFunc.alias + ">"
+            else:
+                result += "</" + codecs.decode(textFunc.alias, encoding) + ">"
         return result
     except:
         return escape(eval(text))
 
 def strRepl(text):
     if not text:
-        return u""
-    if type(text) is not unicode:
+        return ""
+    if type(text) is not str:
         text = codecs.decode(text, encoding)
     text = text.replace(r'\"', r'\\"')
-    text = u'u"""' + text.replace('"', r'\"') + u'"""'
-    if type(text) is unicode:
+    text = '"""' + text.replace('"', r'\"') + '"""'
+    if type(text) is str:
         return escape(eval(text))
 
 def applyMacros(macros, text):
@@ -139,12 +139,12 @@
         self.pointers = {}
         self.macros = {}
         if in_ns:
-            self.alias = in_ns + u":" + name.replace("_", "-")
+            self.alias = in_ns + ":" + name.replace("_", "-")
         else:
             self.alias = name.replace("_", "-")
         pythonFunc["yml_" + name] = self
         if emitlinenumbers:
-            self.values["yml:declared"] = u(line)
+            self.values["yml:declared"] = line
 
     def copy(self, newName):
         yf = YF(newName)
@@ -197,23 +197,23 @@
                                 val = evalPython(val[1][0])
                         if val[0] == "*":
                             val = pointer(val)
-                        if u(val)[0] == '"' or u(val)[0] == "'":
-                            vals[parm] = evalPython(u(val))
+                        if val[0] == '"' or val[0] == "'":
+                            vals[parm] = evalPython(val)
                         else:
-                            vals[parm] = u(val)
+                            vals[parm] = val
                 elif data[0] == "content":
                     hasContent = True
 
         if enable_tracing:
-            text = u(parms) + u", " + u(vals)
-            pointers["_trace_info"] = u'"' + u(line) + u": " + u(self.name) + u" " + text.replace(u'"', u'#') + u'"'
+            text = parms + ", " + vals
+            pointers["_trace_info"] = '"' + line + ": " + self.name + " " + text.replace('"', '#') + '"'
 
         if emitlinenumbers:
             global first
             if first:
-                vals["xmlns:yml"] = u"http://fdik.org/yml"
+                vals["xmlns:yml"] = "http://fdik.org/yml"
                 first = False
-            vals["yml:called"] = u(line)
+            vals["yml:called"] = line
         return self.xml(parms, vals, hasContent, avoidTag)
 
     def addParm(self, parm):
@@ -231,17 +231,17 @@
             self.descends.append(desc)
 
     def addValue(self, parm, value):
-        if type(value) is str or type(value) is unicode:
+        if type(value) is str:
             if value[0] != "'" and value[0] != '"':
-                self.values[parm] = u(value)
-            else:
-                self.values[parm] = u(evalPython(value))
-        else:
-            self.values[parm] = u(evalPython(u(value)))
+                self.values[parm] = value
+            else:
+                self.values[parm] = evalPython(value)
+        else:
+            self.values[parm] = evalPython(value)
 
     def xml(self, callParms, callValues, hasContent, avoidTag = False):
         global pointers
-        extraContent = u""
+        extraContent = ""
         if self.content:
             hasContent = True
         resultParms = self.values.copy()
@@ -259,34 +259,33 @@
         for cp in callParms:
             if i < len(self.parms):
                 if self.parms[i][0] == "*":
-                    cp = u(cp)
                     if "'" in cp:
-                        pointers[self.parms[i][1:]] = u'"' + cp + u'"'
+                        pointers[self.parms[i][1:]] = '"' + cp + '"'
                     else:
-                        pointers[self.parms[i][1:]] = u"'" + cp + u"'"
+                        pointers[self.parms[i][1:]] = "'" + cp + "'"
                 elif self.parms[i][0] == "%":
-                    macros[self.parms[i]] = u(cp)
+                    macros[self.parms[i]] = cp
                 else:
                     resultParms[self.parms[i]] = cp
             else:
-                extraContent += u(cp)
+                extraContent += cp
                 hasContent = True
             i += 1
-        result = u""
+        result = ""
         for p, v in resultParms.iteritems():
             if p[0] == "'" or p[0] == '"':
                 p = eval(p)
-            result += u" "+ p + u"=" + quoteattr(applyMacros(macros, u(v)))
+            result += " "+ p + "=" + quoteattr(applyMacros(macros, v))
         if hasContent:
             if avoidTag:
                 return True, strRepl(extraContent)
             else:
-                return True, u"<" + self.alias + result + u">" + strRepl(extraContent)
+                return True, "<" + self.alias + result + ">" + strRepl(extraContent)
         else:
             if avoidTag:
-                return False, u""
-            else:
-                return False, u"<" + self.alias + result + u"/>"
+                return False, ""
+            else:
+                return False, "<" + self.alias + result + "/>"
 
 def replaceContent(tree, subtree):
     n = 0
@@ -313,7 +312,7 @@
     return tree
 
 def executeCmd(text):
-    if type(text) is not unicode:
+    if type(text) is not str:
         text = codecs.decode(text, encoding)
     for (regex, pattern) in operator:
         match = re.search(regex, text)
@@ -321,11 +320,11 @@
             cmd = pattern
             opt = match.groups()
             for i in range(len(opt)):
-                cmd = cmd.replace(u"%" + u(i+1), opt[i])
-            text = text[:match.start()] + u"`" + cmd + u"`"+ text[match.end():]
+                cmd = cmd.replace("%" + str(i+1), opt[i])
+            text = text[:match.start()] + "`" + cmd + "`"+ text[match.end():]
             match = re.search(regex, text)
 
-    result = u""
+    result = ""
     m = re.search(bq, text)
     while text and m:
         cmd  = m.group(1)
@@ -336,9 +335,9 @@
             if rest: raise SyntaxError(cmd)
         except SyntaxError:
             if included:
-                raise SyntaxError(u"in " + included + u":" + u(line) + u": syntax error in executing command: " + cmd.strip())
-            else:
-                raise SyntaxError(u"in " + u(line) + u": syntax error in executing command: " + cmd.strip())
+                raise SyntaxError("in " + included + ":" + line + ": syntax error in executing command: " + cmd.strip())
+            else:
+                raise SyntaxError("in " + line + ": syntax error in executing command: " + cmd.strip())
         inner = _finish(r)
         result += head + inner
         m = re.search(bq, text)
@@ -358,20 +357,20 @@
     except: pass
 
     if ctype == "empty":
-        return code(u"")
+        return code("")
 
     if ctype == "in_ns":
         in_ns = obj[1][0]
         subtree = obj[1]
         for sel in subtree:
             codegen(sel)
-        in_ns = u""
-        return code(u"")
+        in_ns = ""
+        return code("")
 
     elif ctype == "decl":
-        name = u""
+        name = ""
         for data in obj[1]:
-            if type(data) is unicode or type(data) is str:
+            if type(data) is str:
                 name = data
                 try:
                     yf = ymlFunc[name]
@@ -380,7 +379,7 @@
                     ymlFunc[name] = YF(name)
                     yf = ymlFunc[name]
                     if in_ns:
-                        yf.alias = in_ns + u":" + name
+                        yf.alias = in_ns + ":" + name
                         if not enable_tracing:
                             if in_ns == "xsl" and (name == "debug" or name=="assert" or name[:7]=="_trace_"):
                                 yf.alias = "-"
@@ -394,9 +393,9 @@
                         yf = ymlFunc[name] = ymlFunc[base].copy(name)
                     except KeyError:
                         if included:
-                            raise KeyError(u"in " + included + u":" + u(line) + u": " + base + u" as base for " + name)
+                            raise KeyError("in " + included + ":" + line + ": " + base + " as base for " + name)
                         else:
-                            raise KeyError(u"in " + u(line) + u": " + base + u" as base for " + name)
+                            raise KeyError("in " + line + ": " + base + " as base for " + name)
                 elif data[0] == "shape":
                     shape = ymlFunc[data[1]]
                     try:
@@ -404,9 +403,9 @@
                         yf.patch(shape)
                     except KeyError:
                         if included:
-                            raise KeyError(u"in " + included + u":" + u(line) + u": " + base + u" as shape for " + name)
+                            raise KeyError("in " + included + ":" + line + ": " + base + " as shape for " + name)
                         else:
-                            raise KeyError(u"in " + u(line) + u": " + base + u" as shape for " + name)
+                            raise KeyError("in " + line + ": " + base + " as shape for " + name)
                 elif data[0] == "descend":
                     yf.addDescend(data[1])
                 elif data[0] == "declParm":
@@ -422,23 +421,23 @@
                             yf.pointers[parmName[1:]] = value
                             yf.addParm(parmName)
                         elif parmName[0] == "%":
-                            if type(value) is unicode or type(value) is str:
-                                yf.macros[parmName] = u(evalPython(value))
+                            if type(value) is str:
+                                yf.macros[parmName] = evalPython(value)
                             else:
-                                yf.macros[parmName] = u(evalPython(u(value)))
+                                yf.macros[parmName] = evalPython(value)
                             yf.addParm(parmName)
                 elif data[0] == "alias":
                     if in_ns:
-                        yf.alias = in_ns + u":" + data[1][0]
+                        yf.alias = in_ns + ":" + data[1][0]
                     else:
                         yf.alias = data[1][0]
                 elif data[0] == "content":
                     yf.content = data[1]
 
-        return code(u"")
+        return code("")
 
     elif ctype == "funclist":
-        result = u""
+        result = ""
         for f in obj[1]:
             result += codegen(f)
         return code(result)
@@ -447,13 +446,13 @@
         if len(obj[1]):
             return codegen(('func', ['_parentheses', ('content', [obj[1][0]])]))
         else:
-            return u""
+            return ""
 
     elif ctype == "fparm":
         if len(obj[1]):
             return codegen(('func', ['_parm', ('content', [obj[1][0]])]))
         else:
-            return u""
+            return ""
 
     elif ctype == "generic":
         return codegen(('func', ['_generic', ('content', [obj[1][0]])]))
@@ -468,15 +467,15 @@
         if name == "decl":
             if ymlFunc[name] == "#error":
                 if included:
-                    raise SyntaxError(u"in " + included + u":" + u(line) + u": syntax error in decl statement")
+                    raise SyntaxError("in " + included + ":" + line + ": syntax error in decl statement")
                 else:
-                    raise SyntaxError(u"in " + u(line) + u": syntax error in decl statement")
+                    raise SyntaxError("in " + line + ": syntax error in decl statement")
         if name == "define" or name == "operator":
             if ymlFunc[name] == "#error":
                 if included:
-                    raise SyntaxError(u"in " + included + u":" + u(line) + u": syntax error in define statement")
+                    raise SyntaxError("in " + included + ":" + line + ": syntax error in define statement")
                 else:
-                    raise SyntaxError(u"in " + u(line) + u": syntax error in define statement")
+                    raise SyntaxError("in " + line + ": syntax error in define statement")
 
         if name[0] == "&":
             avoidTag = True
@@ -485,7 +484,7 @@
 
         if len(name) > 2:
             if name[0:2] == "**":
-                return code(eval('u'+pointer(name[1:])))
+                return code(eval(''+pointer(name[1:])))
 
         if name[0] == "*":
             name = eval(pointer(name))
@@ -508,9 +507,9 @@
         if len(ymlFunc[name].descends):
             if obj[1][-1][0] != 'content':
                 if included:
-                    raise KeyError(u"in " + included + u":" + u(line) + u": " + name + u" has descending attributes, but no descendants are following")
+                    raise KeyError("in " + included + ":" + line + ": " + name + " has descending attributes, but no descendants are following")
                 else:
-                    raise KeyError(u"in " + u(line) + u": " + name + u" has descending attributes, but no descendants are following")
+                    raise KeyError("in " + line + ": " + name + " has descending attributes, but no descendants are following")
 
             def first_func(obj):
                 if type(obj) is tuple or type(obj) is Symbol:
@@ -559,7 +558,7 @@
                         if dname[0] == "*":
                             pointers[dname[1:]] = "'" + f[1][0] + "'"
                         else:
-                            add_params.append( ('parm', [dname, u"'" + f[1][0] + u"'"]) )
+                            add_params.append( ('parm', [dname, "'" + f[1][0] + "'"]) )
                         try:
                             add_params.extend( get_parms(f) )
                         except: pass
@@ -571,14 +570,14 @@
                     to_add.append( ('func', new_things ) )
             except:
                 if included:
-                    raise KeyError(u"in " + included + u":" + u(line) + u": " + name + u" has descending attributes, and too less descendants are following")
+                    raise KeyError("in " + included + ":" + line + ": " + name + " has descending attributes, and too less descendants are following")
                 else:
-                    raise KeyError(u"in " + u(line) + u": " + name + u" has descending attributes, and too less descendants are following")
+                    raise KeyError("in " + line + ": " + name + " has descending attributes, and too less descendants are following")
 
         if not to_add:
             to_add = ( obj, )
 
-        complete = u""
+        complete = ""
 
         for obj in to_add:
             subtree = None
@@ -602,14 +601,14 @@
                     result += codegen(sel)
 
             if hasContent and not(avoidTag):
-                result += u"</" + ymlFunc[name].alias + u">"
+                result += "</" + ymlFunc[name].alias + ">"
 
             complete += result
 
         return code(complete)
 
     elif ctype == "textsection":
-        result = u''
+        result = ''
         ll = obj[1].splitlines()
         space = len(ll[-1]) - 2
         for l in ll[1:-1]:
@@ -622,15 +621,15 @@
                     result += _finish(r)
                 except SyntaxError:
                     if included:
-                        raise SyntaxError(u"in " + included + u":" + u(line) + u": syntax error in executing command: " + cmd.strip())
+                        raise SyntaxError("in " + included + ":" + line + ": syntax error in executing command: " + cmd.strip())
                     else:
-                        raise SyntaxError(u"in " + u(line) + u": syntax error in executing command: " + cmd.strip())
-            else:
-                result += codegen(Symbol(u'lineQuote', u'| ' + l[space:]))
+                        raise SyntaxError("in " + line + ": syntax error in executing command: " + cmd.strip())
+            else:
+                result += codegen(Symbol('lineQuote', '| ' + l[space:]))
         return code(result)
 
-    elif ctype == "textsectionu":
-        result = u''
+    elif ctype == "textsection":
+        result = ''
         ll = obj[1].splitlines()
         space = len(ll[-1]) - 2
         for l in ll[1:-1]:
@@ -643,16 +642,16 @@
                     result += _finish(r)
                 except SyntaxError:
                     if included:
-                        raise SyntaxError(u"in " + included + u":" + u(line) + u": syntax error in executing command: " + cmd.strip())
+                        raise SyntaxError("in " + included + ":" + line + ": syntax error in executing command: " + cmd.strip())
                     else:
-                        raise SyntaxError(u"in " + u(line) + u": syntax error in executing command: " + cmd.strip())
-            else:
-                if result != u'': result += u' '
-                result += codegen(Symbol(u'quote', [u'> ' + l[space:]]))
+                        raise SyntaxError("in " + line + ": syntax error in executing command: " + cmd.strip())
+            else:
+                if result != '': result += ' '
+                result += codegen(Symbol('quote', ['> ' + l[space:]]))
         return code(result)
 
     elif ctype == "lineQuote" or ctype == "quote":
-        m, text, base, inds = None, u"", 0, 0
+        m, text, base, inds = None, "", 0, 0
 
         if ctype == "lineQuote":
             text = obj[1]
@@ -670,20 +669,20 @@
                     inds = int(m.group(1))
                 text = m.group(2)[1:]
             else:
-                if type(text) is unicode or type(text) is str:
-                    text = u(evalPython(text))
-
-        ind = u""
+                if type(text) is str:
+                    text = evalPython(text)
+
+        ind = ""
         if inds > -1:
             try:
-                cmd = evalPython(u"indent(" + u(inds) + u")")
-                result, rest = parseLine(u(cmd), _inner, [], True, comment)
+                cmd = evalPython("indent(" + inds + ")")
+                result, rest = parseLine(cmd, _inner, [], True, comment)
                 if rest:
                     raise SyntaxError()
                 ind = _finish(result)
             except: pass
         
-        if ctype == "lineQuote": text += u"\n"
+        if ctype == "lineQuote": text += "\n"
 
         hasTextFunc = False
         try:
@@ -697,13 +696,13 @@
     elif ctype == "tagQuote":
         m = tq.match(obj[1])
         if m.group(1) == "<":
-            return code(u"<" + m.group(2))
+            return code("<" + m.group(2))
         else:
             return code(m.group(2))
 
     elif ctype == "operator":
         operator.append((re.compile(evalPython(obj[1][0])), obj[1][1]))
-        return code(u"")
+        return code("")
 
     elif ctype == "constant":
         name = obj[1][0]
@@ -711,7 +710,7 @@
             name = name[1:]
         value = obj[1][1]
         pointers[name] = value
-        return code(u"")
+        return code("")
 
     elif ctype == "include":
         reverse = False
@@ -724,7 +723,7 @@
                     ktext = True
                 elif arg[0] == "kxml":
                     kxml = True
-            elif type(arg) is unicode or type(arg) is str:
+            elif type(arg) is str:
                 filemask = arg
 
         if filemask[0] == '/' or filemask[0] == '.':
@@ -740,14 +739,14 @@
 
         if not(files):
             if included:
-                raise IOError(u"in " + included + ":" + u(line) + u": include file(s) '" + filemask + u"' not found")
-            else:
-                raise IOError(u"in " + u(line) + u": include file(s) '" + filemask + u"' not found")
+                raise IOError("in " + included + ":" + line + ": include file(s) '" + filemask + "' not found")
+            else:
+                raise IOError("in " + line + ": include file(s) '" + filemask + "' not found")
 
         includeFile = fileinput.input(files, mode="rU", openhook=fileinput.hook_encoded(encoding))
         _included = included
         if ktext or kxml:
-            text = u""
+            text = ""
             for line in includeFile:
                 included = includeFile.filename()
                 if kxml:
@@ -759,7 +758,7 @@
             return code(text)
         else:
             result = parse(ymlCStyle(), includeFile, True, comment)
-            included = u(filemask)
+            included = filemask
             x = _finish(result)
             included = _included
             return code(x)
@@ -767,7 +766,7 @@
     elif ctype == "pyExp":
         exp = obj[1][0]
         cmd = evalPython(exp)
-        result, rest = parseLine(u(cmd), _inner, [], True, comment)
+        result, rest = parseLine(cmd, _inner, [], True, comment)
         if rest:
             raise SyntaxError(cmd)
         return code(_finish(result))
@@ -776,7 +775,7 @@
         parms = []
         data = obj[1]
         for p in data:
-            if type(p) is unicode or type(p) is str:
+            if type(p) is str:
                 name = p
             elif type(p) is tuple or type(p) is Symbol:
                 ptype = p[0]
@@ -786,43 +785,43 @@
                     else:
                         parms.append(p[1][0])
         if len(parms) == 0:
-            exp = name + u"()"
+            exp = name + "()"
         elif len(parms) == 1:
-            exp = name + u"(" + u(parms[0]) + u")"
-        else:
-            exp = name + u(tuple(parms))
+            exp = name + "(" + parms[0] + ")"
+        else:
+            exp = name + tuple(parms)
         cmd = evalPython(exp)
-        result, rest = parseLine(u(cmd), _inner, [], True, comment)
+        result, rest = parseLine(cmd, _inner, [], True, comment)
         if rest:
             raise SyntaxError()
         return code(_finish(result))
 
     else:
-        return code(u"")
+        return code("")
 
 def _finish(tree):
-    result = u""
-    python = u""
+    result = ""
+    python = ""
 
     for el in tree:
         if el[0] == "python":
             if el[1][0][:2] == "!!":
                 python += el[1][0][2:-2]
             else:
-                python += el[1][0][1:] + u"\n"
+                python += el[1][0][1:] + "\n"
             continue
         else:
             if python:
                 execPython(python)
-                python = u""
+                python = ""
 
         try:
             result += codegen(el)
         except RuntimeError:
             if included:
-                raise RuntimeError(u"in " + included + u":" + u(line))
-            else:
-                raise RuntimeError(u"in " + u(line))
+                raise RuntimeError("in " + included + ":" + line)
+            else:
+                raise RuntimeError("in " + line)
 
     if python:
         execPython(python)
--- a/pyPEG.py	Tue Nov 20 22:35:38 2018 +0100
+++ b/pyPEG.py	Fri Jan 25 23:31:57 2019 +0100
@@ -4,10 +4,9 @@
 
 import re
 import sys, codecs
-import exceptions
-
-class keyword(unicode): pass
-class code(unicode): pass
+
+class keyword(str): pass
+class code(str): pass
 class ignore(object):
     def __init__(self, regex_text, *args):
         self.regex = re.compile(regex_text, *args)
@@ -18,10 +17,10 @@
 
 class _not(_and): pass
 
-class Name(unicode):
+class Name(str):
     def __init__(self, *args):
         self.line = 0
-        self.file = u""
+        self.file = ""
 
 class Symbol(list):
     def __init__(self, name, what):
@@ -31,28 +30,16 @@
         self.append(what)
     def __call__(self):
         return self.what
-    def __unicode__(self):
-        return u'Symbol(' + repr(self.__name__) + ', ' + repr(self.what) + u')'
+    def __str__(self):
+        return 'Symbol(' + repr(self.__name__) + ', ' + repr(self.what) + ')'
     def __repr__(self):
-        return unicode(self)
-
-word_regex = re.compile(ur"\w+")
-rest_regex = re.compile(ur".*")
+        return str(self)
+
+word_regex = re.compile(r"\w+")
+rest_regex = re.compile(r".*")
 
 print_trace = False
 
-def u(text):
-    if isinstance(text, exceptions.BaseException):
-        text = text.args[0]
-    if type(text) is unicode:
-        return text
-    if isinstance(text, str):
-        if sys.stdin.encoding:
-            return codecs.decode(text, sys.stdin.encoding)
-        else:
-            return codecs.decode(text, "utf-8")
-    return unicode(text)
-
 def skip(skipper, text, skipWS, skipComments):
     if skipWS:
         t = text.lstrip()
@@ -104,7 +91,7 @@
                 if print_trace:
                     try:
                         if _pattern.__name__ != "comment":
-                            sys.stderr.write(u"match: " + _pattern.__name__ + u"\n")
+                            sys.stderr.write("match: " + _pattern.__name__ + "\n")
                     except: pass
 
             if self.restlen == -1:
@@ -146,7 +133,7 @@
                 if print_trace:
                     try:
                         if pattern.__name__ != "comment":
-                            sys.stderr.write(u"testing with " + pattern.__name__ + u": " + textline[:40] + u"\n")
+                            sys.stderr.write("testing with " + pattern.__name__ + ": " + textline[:40] + "\n")
                     except: pass
 
             if pattern.__name__[0] != "_":
@@ -160,7 +147,7 @@
 
         pattern_type = type(pattern)
 
-        if pattern_type is str or pattern_type is unicode:
+        if pattern_type is str:
             if text[:len(pattern)] == pattern:
                 text = skip(self.skipper, text[len(pattern):], skipWS, skipComments)
                 return R(None, text)
@@ -251,11 +238,11 @@
                 syntaxError()
 
         else:
-            raise SyntaxError(u"illegal type in grammar: " + u(pattern_type))
+            raise SyntaxError("illegal type in grammar: " + pattern_type)
 
     def lineNo(self):
-        if not(self.lines): return u""
-        if self.restlen == -1: return u""
+        if not(self.lines): return ""
+        if self.restlen == -1: return ""
         parsed = self.textlen - self.restlen
 
         left, right = 0, len(self.lines)
@@ -266,20 +253,20 @@
                 try:
                     if self.lines[mid + 1][0] >= parsed:
                         try:
-                            return u(self.lines[mid + 1][1]) + u":" + u(self.lines[mid + 1][2])
+                            return self.lines[mid + 1][1] + ":" + self.lines[mid + 1][2]
                         except:
-                            return u""
+                            return ""
                     else:
                         left = mid + 1
                 except:
                     try:
-                        return u(self.lines[mid + 1][1]) + u":" + u(self.lines[mid + 1][2])
+                        return self.lines[mid + 1][1] + ":" + self.lines[mid + 1][2]
                     except:
-                        return u""
+                        return ""
             else:
                 right = mid - 1
             if left > right:
-                return u""
+                return ""
 
 # plain module API
 
@@ -308,14 +295,14 @@
     while callable(language):
         language = language()
 
-    orig, ld = u"", 0
+    orig, ld = "", 0
     for line in lineSource:
         if lineSource.isfirstline():
             ld = 1
         else:
             ld += 1
         lines.append((len(orig), lineSource.filename(), lineSource.lineno() - 1))
-        orig += u(line)
+        orig += line
 
     textlen = len(orig)
 
@@ -331,10 +318,10 @@
         if text:
             raise SyntaxError()
 
-    except SyntaxError, msg:
+    except SyntaxError as msg:
         parsed = textlen - p.restlen
         textlen = 0
-        nn, lineNo, file = 0, 0, u""
+        nn, lineNo, file = 0, 0, ""
         for n, ld, l in lines:
             if n >= parsed:
                 break
@@ -346,6 +333,6 @@
         lineNo += 1
         nn -= 1
         lineCont = orig.splitlines()[nn]
-        raise SyntaxError(u"syntax error in " + u(file) + u":" + u(lineNo) + u": " + lineCont)
+        raise SyntaxError("syntax error in " + file + ":" + lineNo + ": " + lineCont)
 
     return result
--- a/samples/adressliste.yml2	Tue Nov 20 22:35:38 2018 +0100
+++ b/samples/adressliste.yml2	Fri Jan 25 23:31:57 2019 +0100
@@ -1,12 +1,12 @@
-liste {
-    adresse {
+list {
+    adress {
         name "Meier";
-        strasse "Uhlmannstrasse 42";
-        ort "Laupheim";
+        street "Uhlmannstrasse 42";
+        village "Laupheim";
     }
     adresse {
         name "Schmidt";
-        strasse "Haupstrasse 23";
-        ort "Bad Waldsee";
+        street "Haupstrasse 23";
+        village "Bad Waldsee";
     }
 }
--- a/samples/gen_addr_html.ysl2	Tue Nov 20 22:35:38 2018 +0100
+++ b/samples/gen_addr_html.ysl2	Fri Jan 25 23:31:57 2019 +0100
@@ -1,13 +1,19 @@
 include yslt.yml2
 
-stylesheet {
+estylesheet {
     template "/list" html {
         head title "address list";
-        body table style="border-style=solid;" apply "address";
+        body table style="border-style=solid;"
+            apply "address";
     }
     template "address" tr {
         td value "name";
         td value "street";
-        td value "city";
+        td value "village";
+    }
+    template "address[name='Schmidt']" tr {
+        td value "name";
+        td value "street";
+        td value "village";
     }
 }
--- a/yml2.py	Tue Nov 20 22:35:38 2018 +0100
+++ b/yml2.py	Fri Jan 25 23:31:57 2019 +0100
@@ -44,12 +44,12 @@
 macro = r(r"\%" + _symbol, re.U)
 reference = r(r"\&" + _symbol, re.U)
 
-NameStartChar = ur''':|[A-Z]|_|[a-z]|[\u00C0-\u00D6]|[\u00D8-\u00F6]|[\u00F8-\u02FF]|[\u0370-\u037D]|[\u037F-\u1FFF]|[\u200C-\u200D]|[\u2070-\u218F]|[\u2C00-\u2FEF]|[\u3001-\uD7FF]|[\uF900-\uFDCF]|[\uFDF0-\uFFFD]'''
-NameChar = NameStartChar + ur'''|-|\.|[0-9]|\u00B7|[\u0300-\u036F]|[\u203F-\u2040]'''
+NameStartChar = r''':|[A-Z]|_|[a-z]|[\u00C0-\u00D6]|[\u00D8-\u00F6]|[\u00F8-\u02FF]|[\u0370-\u037D]|[\u037F-\u1FFF]|[\u200C-\u200D]|[\u2070-\u218F]|[\u2C00-\u2FEF]|[\u3001-\uD7FF]|[\uF900-\uFDCF]|[\uFDF0-\uFFFD]'''
+NameChar = NameStartChar + r'''|-|\.|[0-9]|\u00B7|[\u0300-\u036F]|[\u203F-\u2040]'''
 
-_xmlSymbol = u"(" + NameStartChar + u")(" + NameChar + u")*"
+_xmlSymbol = "(" + NameStartChar + ")(" + NameChar + ")*"
 xmlSymbol = r(_xmlSymbol)
-aliasSymbol = r(ur"-|(" + _xmlSymbol + ur")")
+aliasSymbol = r(r"-|(" + _xmlSymbol + r")")
 
 literal = [r(r'""".*?"""', re.S), r(r"'''.*?'''", re.S), r(r"""-?\d+\.\d*|-?\.\d+|-?\d+|".*?"|'.*?'""")]
 filename = [("'", r(r"[^']*"), "'"), ('"', r(r'[^"]*'), '"'), r(r"[^\s;]+")]
--- a/yml2c	Tue Nov 20 22:35:38 2018 +0100
+++ b/yml2c	Fri Jan 25 23:31:57 2019 +0100
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 # vim: set fileencoding=utf-8 :
 
 """\
@@ -11,21 +11,17 @@
 import fileinput, unicodedata
 from optparse import OptionParser
 
-from pyPEG import parse, u
+from pyPEG import parse
 from yml2 import ymlCStyle, comment, oldSyntax
 import backend
 
 def printInfo(option, opt_str, value, parser):
     sys.stdout.write(__doc__)
+    sys.exit(0)
 
 def w(msg):
     if isinstance(msg, BaseException):
-        try:
-            msg = str(msg) + "\n"
-        except:
-            msg = u(msg) + u"\n"
-    if type(msg) is unicode:
-        msg = codecs.encode(msg, sys.stderr.encoding)
+        msg = str(msg) + "\n"
     sys.stderr.write(msg)
 
 optParser = OptionParser()
@@ -86,10 +82,10 @@
     w("\n")
     sys.exit(1)
 except KeyError as msg:
-    w(u"not found: " + u(msg) + u"\n")
+    w("not found: " + msg + "\n")
     sys.exit(4)
 except LookupError as msg:
-    w(u"not found: " + u(msg) + u"\n")
+    w("not found: " + msg + "\n")
     sys.exit(4)
 except Exception as msg:
     w(msg)
--- a/yml2proc	Tue Nov 20 22:35:38 2018 +0100
+++ b/yml2proc	Fri Jan 25 23:31:57 2019 +0100
@@ -18,7 +18,7 @@
     sys.exit(1)
 
 from yml2 import ymlCStyle, comment, oldSyntax
-from pyPEG import parse, u
+from pyPEG import parse
 import backend
 
 def printInfo(option, opt_str, value, parser):
@@ -33,7 +33,7 @@
             msg = str(msg) + "\n"
         except:
             msg = u(msg) + u"\n"
-    if type(msg) is unicode:
+    if type(msg) is str:
         msg = codecs.encode(msg, sys.stderr.encoding)
     sys.stderr.write(msg)
 
@@ -182,7 +182,7 @@
         if options.params:
             params = eval(options.params)
             for key, value in params.iteritems():
-                if type(value) != unicode:
+                if type(value) != str:
                     params[key] = u(value)
         if options.stringparams:
             for key, value in eval(options.stringparams).iteritems():
@@ -203,7 +203,7 @@
     if options.pretty:
         plaintext = etree.tostring(etree.fromstring(rtext), pretty_print=True, xml_declaration=True, encoding=options.encoding)
     else:
-        if isinstance(rtext, unicode):
+        if isinstance(rtext, str):
             plaintext = codecs.encode(rtext, options.encoding)
         else:
             plaintext = str(rtext)