parser.py 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. import sys
  2. from external.graph_drawing.graph import generate_graph
  3. from external.graph_drawing.line import generate_line
  4. class ParserWrapper(object):
  5. def __init__(self, base_class, **kwargs):
  6. self.input_buffer = []
  7. self.last_buffer = ''
  8. self.input_position = 0
  9. self.closed = False
  10. self.verbose = kwargs.get('verbose', False)
  11. self.parser = base_class(file=self, read=self.read, **kwargs)
  12. def readline(self, nbytes=False):
  13. return self.read(nbytes)
  14. def read(self, nbytes=False):
  15. if len(self.last_buffer) >= nbytes:
  16. buf = self.last_buffer[:nbytes]
  17. self.last_buffer = self.last_buffer[nbytes:]
  18. return buf
  19. buf = self.last_buffer
  20. try:
  21. buf += self.input_buffer[self.input_position]
  22. if self.verbose:
  23. print 'read:', buf
  24. self.input_position += 1
  25. except IndexError:
  26. self.closed = True
  27. return ''
  28. self.last_buffer = buf[nbytes:]
  29. return buf
  30. def close(self):
  31. self.closed = True
  32. self.input_position = len(self.input_buffer)
  33. def run(self, input_buffer, *args, **kwargs):
  34. map(self.append, input_buffer)
  35. return self.parser.run(*args, **kwargs)
  36. def append(self, input):
  37. self.closed = False
  38. self.input_buffer.append(input + '\n')
  39. def run_expressions(base_class, expressions, keepfiles=1, fail=True,
  40. silent=False, verbose=0):
  41. """
  42. Run a list of mathematical expression through the term rewriting system and
  43. check if the output matches the expected output. The list of EXPRESSIONS
  44. consists of tuples (expression, output), where expression is the
  45. mathematical expression to evaluate (String) and output is the expected
  46. output of the evaluation (thus, the output can be Float, Int or None).
  47. If KEEPFILES is non-zero or True, the generated Flex and Bison files will
  48. be kept. Otherwise, those temporary files will be deleted. If FAIL is True,
  49. and the output of the expression is not equal to the expected output, an
  50. assertion error is raised. If SILENT is False, and an assertion error is
  51. raised, an error message is printed on stderr. If SILENT is True, no error
  52. message will be printed.
  53. If VERBOSE is non-zero and a positive integer number, verbosity of the term
  54. rewriting system will be increased. This will output debug messages and a
  55. higher value will print more types of debug messages.
  56. """
  57. parser = ParserWrapper(base_class, keepfiles=keepfiles, verbose=verbose)
  58. for exp, out in expressions:
  59. res = None
  60. try:
  61. res = parser.run([exp])
  62. assert res == out
  63. except: # pragma: nocover
  64. if not silent:
  65. print >>sys.stderr, 'error: %s = %s, but expected: %s' \
  66. % (exp, str(res), str(out))
  67. if not silent and hasattr(res, 'nodes'):
  68. print >>sys.stderr, 'result graph:'
  69. print >>sys.stderr, generate_graph(res)
  70. print >>sys.stderr, 'expected graph:'
  71. print >>sys.stderr, generate_graph(out)
  72. if fail:
  73. raise
  74. def graph(parser, *exp, **kwargs):
  75. return generate_graph(ParserWrapper(parser, **kwargs).run(exp))
  76. def line(parser, *exp, **kwargs):
  77. return generate_line(ParserWrapper(parser, **kwargs).run(exp))