This repo contains code to mirror other repos. It also contains the code that is getting mirrored.
25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

148 lines
4.3 KiB

  1. from __future__ import absolute_import
  2. from unittest import TestCase, main
  3. from lark import Lark, Tree, Transformer
  4. from lark.lexer import Lexer, Token
  5. import lark.lark as lark_module
  6. try:
  7. from StringIO import StringIO
  8. except ImportError:
  9. from io import BytesIO as StringIO
  10. class MockFile(StringIO):
  11. def close(self):
  12. pass
  13. def __enter__(self):
  14. return self
  15. def __exit__(self, *args):
  16. pass
  17. class MockFS:
  18. def __init__(self):
  19. self.files = {}
  20. def open(self, name, mode=None):
  21. if name not in self.files:
  22. f = self.files[name] = MockFile()
  23. else:
  24. f = self.files[name]
  25. f.seek(0)
  26. return f
  27. def exists(self, name):
  28. return name in self.files
  29. class CustomLexer(Lexer):
  30. def __init__(self, lexer_conf):
  31. pass
  32. def lex(self, data):
  33. for obj in data:
  34. yield Token('A', obj)
  35. class InlineTestT(Transformer):
  36. def add(self, children):
  37. return sum(children if isinstance(children, list) else children.children)
  38. def NUM(self, token):
  39. return int(token)
  40. def __reduce__(self):
  41. raise TypeError("This Transformer should not be pickled.")
  42. def append_zero(t):
  43. return t.update(value=t.value + '0')
  44. class TestCache(TestCase):
  45. g = '''start: "a"'''
  46. def setUp(self):
  47. self.fs = lark_module.FS
  48. self.mock_fs = MockFS()
  49. lark_module.FS = self.mock_fs
  50. def tearDown(self):
  51. self.mock_fs.files = {}
  52. lark_module.FS = self.fs
  53. def test_simple(self):
  54. fn = "bla"
  55. Lark(self.g, parser='lalr', cache=fn)
  56. assert fn in self.mock_fs.files
  57. parser = Lark(self.g, parser='lalr', cache=fn)
  58. assert parser.parse('a') == Tree('start', [])
  59. def test_automatic_naming(self):
  60. assert len(self.mock_fs.files) == 0
  61. Lark(self.g, parser='lalr', cache=True)
  62. assert len(self.mock_fs.files) == 1
  63. parser = Lark(self.g, parser='lalr', cache=True)
  64. assert parser.parse('a') == Tree('start', [])
  65. parser = Lark(self.g + ' "b"', parser='lalr', cache=True)
  66. assert len(self.mock_fs.files) == 2
  67. assert parser.parse('ab') == Tree('start', [])
  68. parser = Lark(self.g, parser='lalr', cache=True)
  69. assert parser.parse('a') == Tree('start', [])
  70. def test_custom_lexer(self):
  71. parser = Lark(self.g, parser='lalr', lexer=CustomLexer, cache=True)
  72. parser = Lark(self.g, parser='lalr', lexer=CustomLexer, cache=True)
  73. assert len(self.mock_fs.files) == 1
  74. assert parser.parse('a') == Tree('start', [])
  75. def test_options(self):
  76. # Test options persistence
  77. Lark(self.g, parser="lalr", debug=True, cache=True)
  78. parser = Lark(self.g, parser="lalr", debug=True, cache=True)
  79. assert parser.options.options['debug']
  80. def test_inline(self):
  81. # Test inline transformer (tree-less) & lexer_callbacks
  82. # Note: the Transformer should not be saved to the file,
  83. # and is made unpickable to check for that
  84. g = """
  85. start: add+
  86. add: NUM "+" NUM
  87. NUM: /\d+/
  88. %ignore " "
  89. """
  90. text = "1+2 3+4"
  91. expected = Tree('start', [30, 70])
  92. parser = Lark(g, parser='lalr', transformer=InlineTestT(), cache=True, lexer_callbacks={'NUM': append_zero})
  93. res0 = parser.parse(text)
  94. parser = Lark(g, parser='lalr', transformer=InlineTestT(), cache=True, lexer_callbacks={'NUM': append_zero})
  95. assert len(self.mock_fs.files) == 1
  96. res1 = parser.parse(text)
  97. res2 = InlineTestT().transform(Lark(g, parser="lalr", cache=True, lexer_callbacks={'NUM': append_zero}).parse(text))
  98. assert res0 == res1 == res2 == expected
  99. def test_imports(self):
  100. g = """
  101. %import .grammars.ab (startab, expr)
  102. """
  103. parser = Lark(g, parser='lalr', start='startab', cache=True, source_path=__file__)
  104. assert len(self.mock_fs.files) == 1
  105. parser = Lark(g, parser='lalr', start='startab', cache=True, source_path=__file__)
  106. assert len(self.mock_fs.files) == 1
  107. res = parser.parse("ab")
  108. self.assertEqual(res, Tree('startab', [Tree('expr', ['a', 'b'])]))
  109. if __name__ == '__main__':
  110. main()