]> hydra-www.ietfng.org Git - dyna2/commitdiff
Tweaks to error messages.
authorTim Vieira <tim.f.vieira@gmail.com>
Sat, 29 Jun 2013 01:51:15 +0000 (21:51 -0400)
committerTim Vieira <tim.f.vieira@gmail.com>
Sat, 29 Jun 2013 01:51:15 +0000 (21:51 -0400)
Improved documentation for loaders and post-processors.

src/Dyna/Backend/Python/errors.py
src/Dyna/Backend/Python/interpreter.py
src/Dyna/Backend/Python/load/__init__.py
src/Dyna/Backend/Python/load/matrix.py
src/Dyna/Backend/Python/load/sexpr.py
src/Dyna/Backend/Python/load/tsv.py
src/Dyna/Backend/Python/repl.py
src/Dyna/Backend/Python/utils.py

index 70a97289abe9828dd6deaad33fbe19002779f482..973f3bd042162f15bee0a6a889b1e23bb2d04281 100644 (file)
@@ -8,19 +8,21 @@ class DynaCompilerError(Exception):
     pass
 
 
-#class AggregatorConflict(Exception):
-#    def __init__(self, key, expected, got):
-#        msg = "Aggregator conflict %r was %r trying to set to %r." \
-#            % (key, expected, got)
-#        super(AggregatorConflict, self).__init__(msg)
-
-
 class DynaInitializerException(Exception):
     def __init__(self, exception, init):
-        msg = '%r in ininitializer for rule\n  %s\n        %s' % \
-            (exception,
-             parse_attrs(init)['Span'],
-             parse_attrs(init)['rule'])
+        rule = parse_attrs(init)['rule']
+        span = parse_attrs(init)['Span']
+
+        if span.startswith(dotdynadir / 'tmp'):
+            # don't show users tmp files create by the repl.
+            msg = '%r in ininitializer for rule\n    %s' % \
+                (exception, rule)
+
+        else:
+            msg = '%r in ininitializer for rule\n  %s\n        %s' % \
+                (exception,
+                 span,
+                 rule)
         super(DynaInitializerException, self).__init__(msg)
 
 
@@ -43,17 +45,22 @@ def exception_handler(etype, evalue, tb):
     # chart -- because it might be too big to email); input to repl.
     # This should all go into a tarball.
 
+    if crash_handler.interp is not None:
+        crash_handler.interp()
+
     print 'FATAL ERROR (%s): %s' % (etype.__name__, evalue)
-    print 'Please report this error by emailing bugs@dyna.org. ' \
-        'Please attach the following file %s' % crashreport.name
+    print 'Crash log available %s' % crashreport.name
 
 
-def enable_crash_handler():
+def crash_handler():
     """
     Use our custom exception handler for handling uncaught exceptions.
     """
     sys.excepthook = exception_handler
 
+# XXX: global state...
+crash_handler.interp = None
+
 
 def show_traceback(einfo=None):
     if not einfo:
index 7e0f8c2828c7cba04d8f7c652fa17c22b8207e52..7fbd3580aae84d5f5dfd6605541973b10be04933 100644 (file)
@@ -204,10 +204,7 @@ from utils import ip, red, green, blue, magenta, yellow, parse_attrs, \
 
 from prioritydict import prioritydict
 from config import dotdynadir
-from errors import notimplemented, enable_crash_handler, \
-    DynaInitializerException, DynaCompilerError
-
-from stdlib import *
+from errors import crash_handler, DynaInitializerException
 
 
 class Rule(object):
@@ -258,6 +255,8 @@ class Interpreter(object):
         self.rules = ddict(Rule)
         self.error = {}
 
+        self.files = []
+
     def __getstate__(self):
         return ((self.chart,
                  self.agenda,
@@ -580,6 +579,11 @@ class Interpreter(object):
 
         return self.go()
 
+    def dynac(self, filename, out=None):
+        self.files.append(filename)
+        out = dynac(filename, out)
+        self.files.append(out)
+
     def dynac_code(self, code):
         """
         Compile a string of dyna code.
@@ -599,7 +603,7 @@ class Interpreter(object):
             f.write(self.parser_state)  # include parser state if any.
             f.write(code)
 
-        dynac(dyna, out)   # might raise compiler error
+        self.dynac(dyna, out)   # might raise compiler error
 
         return out
 
@@ -646,7 +650,23 @@ def main():
 
     interp = Interpreter()
 
-    enable_crash_handler()
+    crash_handler()
+
+
+#    def pickle_interp():
+#        import subprocess
+#
+#        crash = dotdynadir / 'crash'
+#        crash.rmtree(ignore_errors=False)
+#        crash.mkdir_p()
+#
+#        for f in [dotdynadir / 'crash.log'] + interp.files:
+#            path(f).copy(crash)
+#
+#        subprocess.Popen(['tar', 'czf', dotdynadir / 'crash.tar.gz', crash])
+#
+#    crash_handler.interp = pickle_interp
+
 
     if args.source:
 
@@ -658,7 +678,7 @@ def main():
             plan = args.source
         else:
             plan = args.source + '.plan.py'
-            dynac(args.source, plan)
+            interp.dynac(args.source, plan)
 
         if args.profile:
             # When profiling, its common practice to disable the garbage collector.
index 462a3b41b83e87eb091e04ebb7bdbeb729eb68f9..a733071861abe7526f2685f813694f82f8e4aba6 100644 (file)
@@ -1,16 +1,11 @@
-#from sexpr import sexpr
-#from tsv import tsv
-#from matrix import matrix
-#from pickled import pickled
-
-import re as _re
+import re
 from utils import get_module
 
 available = 'sexpr', 'tsv', 'matrix'
 
 def run(interp, line):
     try:
-        [(name, module, args)] = _re.findall('^([a-z][a-zA-Z_0-9]*) = ([a-z][a-zA-Z_0-9]*)\((.*)\)', line)
+        [(name, module, args)] = re.findall('^([a-z][a-zA-Z_0-9]*) = ([a-z][a-zA-Z_0-9]*)\((.*)\)', line)
     except ValueError:
         print 'Error: failed to parse post command.'
         print '    %s' % line
index de827a6a5ca9574aa1ecebc071ecac908823fc45..a3e3171272545c66fdbf350d92c283d8f98ceced 100644 (file)
@@ -1,24 +1,52 @@
-"""
-mat - Load a text file as a (jagged) matrix.
+import re
 
-For example
+class matrix(object):
+    """
+    Load a text file as a (jagged) matrix.
 
-1 2 3
-4 5
+    For example
 
-6 7
+    $ echo 1 2 3 >  /tmp/foo
+    $ echo 4 5   >> /tmp/foo
+    $ echo       >> /tmp/foo
+    $ echo 6 7   >> /tmp/foo
 
+    :- load m = matrix("/tmp/foo")
+    :- sol
 
-m(0,0) := 1. m(0,1) := 2. m(0,2) := 3
-m(1,0) := 4. m(1,1) := 5.
+    Solution
+    ========
+    m/2
+    ===
+    m(0,0) := 1.0
+    m(0,1) := 2.0
+    m(0,2) := 3.0
+    m(1,0) := 4.0
+    m(1,1) := 5.0
+    m(3,0) := 6.0
+    m(3,1) := 7.0
 
-m(3,0) := 6. m(3,1) := 7.
 
-"""
+    As you can see, by default values are interpreted as floats, to specify a
+    different type simple passing a function which will convert strings to the
+    appropriate time (e.g. str, int, float).
 
-import re
+    :- load m = matrix("/tmp/foo", astype=str)
+    :- sol
 
-class matrix(object):
+    Solution
+    ========
+    m/2
+    ===
+    m(0,0) := "1"
+    m(0,1) := "2"
+    m(0,2) := "3"
+    m(1,0) := "4"
+    m(1,1) := "5"
+    m(3,0) := "6"
+    m(3,1) := "7"
+
+    """
 
     def __init__(self, interp, name):
         self.interp = interp
index a4e0d6682a53c4b0940bedf93a9d8e7f64d0ff9a..79837915656876cbfee4f5e9ff5e078243f655f8 100644 (file)
@@ -1,12 +1,24 @@
-"""
-Read lisp-style S-Expressions from a file.
-"""
-
 from cStringIO import StringIO
 from utils import parse_sexpr
 
 
 class sexpr(object):
+    """
+    Read lisp-style S-Expressions from a file.
+
+    $ echo '(a (b c) (d e)) (a b (c))' > /tmp/foo
+    $ ./dyna
+    :- load trees = sexpr("/tmp/foo")
+    :- sol
+
+    Solution
+    ========
+    trees/1
+    =======
+    trees(0) := node("a", node("b", "c"), node("d", "e"))
+    trees(1) := node("a", "b", "c")
+
+    """
 
     def __init__(self, interp, name):
         self.interp = interp
index be67a79b6ee63a29aa784c7cbd145d5a5e24be24..7d0a51e7511ac0e58324d28977b5b49a5089af8b 100644 (file)
@@ -1,12 +1,27 @@
+"""
+TODO: option for stripping comments
+TODO: option for strict number of columns.
+"""
+
 import re
 
 class tsv(object):
-
     """
     Load tab-delimited files.
 
-    TODO: option for stripping comments
-    TODO: option for strict number of columns.
+    :- load row = tsv("test/repl/english.gr")
+    :- sol
+    row/4
+    =====
+    row(0,"0","S","NP VP")         := true
+    row(1,"1.58","ROOT","S .")     := true
+    row(2,"1.58","ROOT","S !")     := true
+    row(3,"1.58","ROOT","VP !")    := true
+    row(4,"3.81","VP","V")         := true
+    row(5,"3.81","VP","V NP")      := true
+    row(6,"1.49","VP","V VP")      := true
+       ...
+
     """
 
     def __init__(self, interp, name):
index 1ebc77b71d11862b9acee23ecf1285bbbb507a3a..f5dfb2eb48c72b3161ab1deab02e8610a1d2ad69 100644 (file)
@@ -139,7 +139,7 @@ class REPL(cmd.Cmd, object):
 
         """
         try:
-            changed = self.interp.do(dynac(filename))
+            changed = self.interp.do(self.interp.dynac(filename))
         except DynaCompilerError as e:
             print e
         else:
index 602f0f3b888f8186736bb11978810a4d87823130..c5b482bf546b4d6ef211130b8a3b792aec126b1e 100644 (file)
@@ -3,8 +3,6 @@ from path import path
 from subprocess import Popen, PIPE
 from IPython.frontend.terminal.embed import InteractiveShellEmbed
 from config import dynahome, dotdynadir
-import signal
-from contextlib import contextmanager
 from collections import namedtuple
 
 
@@ -106,24 +104,26 @@ def subst(term, v):
     return ''.join((_repr(v[x]) if x in v else x) for x in lexer(term))
 
 
-
-@contextmanager
-def interrupt_after():
-
-    def handler(signum, frame):
-        sys.stderr.write('^C')
-        handler.interrupted = True
-        return signal.SIG_IGN
-
-    handler.interrupted = False
-    signal.signal(signal.SIGINT, handler)
-
-    yield
-
-    signal.signal(signal.SIGINT, signal.default_int_handler)
-
-    if handler.interrupted:
-        raise KeyboardInterrupt
+#import signal
+#from contextlib import contextmanager
+#
+#@contextmanager
+#def interrupt_after():
+#
+#    def handler(signum, frame):
+#        sys.stderr.write('^C')
+#        handler.interrupted = True
+#        return signal.SIG_IGN
+#
+#    handler.interrupted = False
+#    signal.signal(signal.SIGINT, handler)
+#
+#    yield
+#
+#    signal.signal(signal.SIGINT, signal.default_int_handler)
+#
+#    if handler.interrupted:
+#        raise KeyboardInterrupt
 
 
 class ddict(dict):