[cig-commits] r15664 - in cs/pythia/trunk/pyre/inventory: . odb pcs

leif at geodynamics.org leif at geodynamics.org
Wed Sep 9 16:16:35 PDT 2009


Author: leif
Date: 2009-09-09 16:16:34 -0700 (Wed, 09 Sep 2009)
New Revision: 15664

Added:
   cs/pythia/trunk/pyre/inventory/pcs/
   cs/pythia/trunk/pyre/inventory/pcs/CodecConfigSheet.py
   cs/pythia/trunk/pyre/inventory/pcs/Lexer.py
   cs/pythia/trunk/pyre/inventory/pcs/Parser.py
   cs/pythia/trunk/pyre/inventory/pcs/__init__.py
Modified:
   cs/pythia/trunk/pyre/inventory/__init__.py
   cs/pythia/trunk/pyre/inventory/odb/Curator.py
Log:
Added support for highly experimental .pcs (Pyre configuration sheet)
input files.  Their syntax is modeled after CSS.


Modified: cs/pythia/trunk/pyre/inventory/__init__.py
===================================================================
--- cs/pythia/trunk/pyre/inventory/__init__.py	2009-09-09 14:07:46 UTC (rev 15663)
+++ cs/pythia/trunk/pyre/inventory/__init__.py	2009-09-09 23:16:34 UTC (rev 15664)
@@ -45,6 +45,11 @@
     return CodecConfig()
 
 
+def codecConfigSheet():
+    from pcs.CodecConfigSheet import CodecConfigSheet
+    return CodecConfigSheet()
+
+
 def renderer(mode="pml"):
     if mode == "pml":
         from pml.Renderer import Renderer

Modified: cs/pythia/trunk/pyre/inventory/odb/Curator.py
===================================================================
--- cs/pythia/trunk/pyre/inventory/odb/Curator.py	2009-09-09 14:07:46 UTC (rev 15663)
+++ cs/pythia/trunk/pyre/inventory/odb/Curator.py	2009-09-09 23:16:34 UTC (rev 15664)
@@ -18,7 +18,7 @@
 class Curator(Base):
 
 
-    def getTraits(self, name, context, encodings=['pml','cfg'], vault=[], extraDepositories=[]):
+    def getTraits(self, name, context, encodings=['pml','cfg','pcs'], vault=[], extraDepositories=[]):
         """load cascade of inventory values for component <name>"""
 
         # initialize the registry object
@@ -309,6 +309,7 @@
         import pyre.inventory
         pml = pyre.inventory.codecPML()
         cfg = pyre.inventory.codecConfig()
+        pcs = pyre.inventory.codecConfigSheet()
 
         import pyre.odb
         odb = pyre.odb.odb()
@@ -316,7 +317,7 @@
         import pyre.templates
         tmpl = pyre.templates.codecTmpl()
 
-        self.registerCodecs(pml, cfg, odb, tmpl)
+        self.registerCodecs(pml, cfg, pcs, odb, tmpl)
 
         return
 

Added: cs/pythia/trunk/pyre/inventory/pcs/CodecConfigSheet.py
===================================================================
--- cs/pythia/trunk/pyre/inventory/pcs/CodecConfigSheet.py	                        (rev 0)
+++ cs/pythia/trunk/pyre/inventory/pcs/CodecConfigSheet.py	2009-09-09 23:16:34 UTC (rev 15664)
@@ -0,0 +1,34 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                      California Institute of Technology
+#                        (C) 2009  All Rights Reserved
+#
+# {LicenseText}
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+
+from pyre.inventory.odb.Registry import Registry
+from pyre.odb.fs.CodecODB import CodecODB
+from Parser import Parser
+
+
+class CodecConfigSheet(CodecODB):
+
+    def __init__(self):
+        CodecODB.__init__(self, encoding='pcs')
+        return
+
+    def _decode(self, shelf):
+        root = Registry("root")
+        parser = Parser(root)
+        parser.parseFile(shelf.name)
+        shelf['inventory'] = root
+        shelf._frozen = True
+        return
+
+
+# end of file

Added: cs/pythia/trunk/pyre/inventory/pcs/Lexer.py
===================================================================
--- cs/pythia/trunk/pyre/inventory/pcs/Lexer.py	                        (rev 0)
+++ cs/pythia/trunk/pyre/inventory/pcs/Lexer.py	2009-09-09 23:16:34 UTC (rev 15664)
@@ -0,0 +1,88 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                      California Institute of Technology
+#                        (C) 2009  All Rights Reserved
+#
+# {LicenseText}
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+
+class Lexer(object):
+
+
+    def __init__(self, input):
+        import re
+        self.regexp = re.compile(r""
+                                 "(?P<leftBrace>{)|"
+                                 "(?P<rightBrace>})|"
+                                 "(?P<colon>:)|"
+                                 "(?P<semicolon>;)|"
+                                 "\"(?P<string>[^\"\n]*)\"|"
+                                 "(?P<newline>\n)|"
+                                 "(?P<word>[^\s{}:;]+)")
+        input = self._stripComments(input)
+        self.tokenIter = self._tokenIter(input)
+        self.lineNo = 1
+        return
+
+
+    def nextToken(self):
+        try:
+            token = self.tokenIter.next()
+            while token.kind == "newline":
+                self.lineNo += 1
+                token = self.tokenIter.next()
+        except StopIteration:
+            token = self.Token("eof", None)
+        return token
+
+
+    def _stripComments(self, input):
+        import re
+
+        # strip single-line comments
+        regexp = re.compile(r"//[^\n]*")
+        input = ''.join(filter(None, regexp.split(input)))
+        
+        # strip multi-line comments
+        regexp = re.compile(r"(/\*)|(\*/)")
+        newlines = re.compile(r"[\n\r]")
+        result = ""
+        inComment = False
+        for chunk in filter(None, regexp.split(input)):
+            if chunk == "/*":
+                assert not inComment, "'/*' inside of comment"
+                inComment = True
+            elif chunk == "*/":
+                assert inComment, "'*/' outside of comment"
+                inComment = False
+            elif inComment:
+                # preserve newlines for the sake of line numbering
+                result += ''.join(newlines.findall(chunk))
+            else:
+                result += chunk
+
+        return result
+            
+
+    def _tokenIter(self, input):
+        for match in self.regexp.finditer(input):
+            yield self.Token(match.lastgroup, match.group(match.lastindex))
+        return
+
+
+    class Token(object):
+
+        __slots__ = ('kind', 'value')
+
+        def __init__(self, kind, value):
+            self.kind = kind
+            self.value = value
+            return
+
+
+# end of file

Added: cs/pythia/trunk/pyre/inventory/pcs/Parser.py
===================================================================
--- cs/pythia/trunk/pyre/inventory/pcs/Parser.py	                        (rev 0)
+++ cs/pythia/trunk/pyre/inventory/pcs/Parser.py	2009-09-09 23:16:34 UTC (rev 15664)
@@ -0,0 +1,125 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                      California Institute of Technology
+#                        (C) 2009  All Rights Reserved
+#
+# {LicenseText}
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+
+class Parser(object):
+
+
+    def __init__(self, root):
+        self.root = root
+        self.lexer = None
+        self.nextToken = None
+        self.acceptedToken = None
+        return
+
+
+    def parseFile(self, pathname):
+        self.pathname = pathname
+        stream = open(pathname, "r")
+        self.lexer = self._createLexer(stream.read())
+        self._parse()
+        return
+
+
+    def _parse(self):
+        self._getToken()
+        while not self._accept("eof"):
+            name = self._parseName()
+            self._expect("leftBrace")
+            childNode = self._getNode(self.root, name)
+            self._parseTraitSet(childNode)
+        return
+
+
+    def _parseTraitSet(self, node):
+        while not self._accept("rightBrace"):
+            name = self._parseName()
+            if self._accept("colon"):
+                self._parseTrait(node, name)
+            elif self._accept("leftBrace"):
+                childNode = self._getNode(node, name)
+                self._parseTraitSet(childNode)
+            else:
+                self._parseError()
+        return
+
+
+    def _parseTrait(self, node, name):
+        if (self._accept("string") or
+            self._accept("word")):
+            pass
+        else:
+            self._parseError()
+        value = self.acceptedToken.value
+        locator = self._getLocator()
+        self._expect("semicolon")
+        key = name[-1]
+        path = name[:-1]
+        node = self._getNode(node, path)
+        node.setProperty(key, value, locator)
+        return
+
+
+    def _parseName(self):
+        self._expect("word")
+        name = self.acceptedToken.value
+        while self._accept("word"):
+            name += self.acceptedToken.value
+        return name.split('.')
+
+
+    def _expect(self, kind):
+        if self._accept(kind):
+            return
+        self._parseError()
+
+
+    def _accept(self, kind):
+        if self.nextToken.kind == kind:
+            self._getToken()
+            return True
+        return False
+
+
+    def _getToken(self):
+        self.acceptedToken = self.nextToken
+        self.nextToken = self.lexer.nextToken()
+        return
+
+
+    def _getNode(self, node, path):
+        if len(path) == 0:
+            return node
+        key = path[0]
+        return self._getNode(node.getNode(key), path[1:])
+
+
+    def _getLocator(self):
+        import pyre.parsing.locators as locators
+        return locators.file(self.pathname, self.lexer.lineNo)
+
+
+    def _createLexer(self, input):
+        from Lexer import Lexer
+        return Lexer(input)
+
+
+    def _parseError(self):
+        raise self.ParseError("line %d: '%s' unexpected" %
+                              (self.lexer.lineNo, self.nextToken.value))
+
+    class ParseError(Exception):
+        pass
+
+
+
+# end of file

Added: cs/pythia/trunk/pyre/inventory/pcs/__init__.py
===================================================================
--- cs/pythia/trunk/pyre/inventory/pcs/__init__.py	                        (rev 0)
+++ cs/pythia/trunk/pyre/inventory/pcs/__init__.py	2009-09-09 23:16:34 UTC (rev 15664)
@@ -0,0 +1,17 @@
+#!/usr/bin/env python
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+#                             Michael A.G. Aivazis
+#                      California Institute of Technology
+#                      (C) 1998-2005  All Rights Reserved
+#
+# <LicenseText>
+#
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+
+# version
+__id__ = "$Id: __init__.py,v 1.1.1.1 2005/03/08 16:13:43 aivazis Exp $"
+
+# End of file 



More information about the CIG-COMMITS mailing list