This repo contains code to mirror other repos. It also contains the code that is getting mirrored.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

143 lines
4.1 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 append_zero(t):
  41. return t.update(value=t.value + '0')
  42. class TestCache(TestCase):
  43. g = '''start: "a"'''
  44. def setUp(self):
  45. self.fs = lark_module.FS
  46. self.mock_fs = MockFS()
  47. lark_module.FS = self.mock_fs
  48. def tearDown(self):
  49. self.mock_fs.files = {}
  50. lark_module.FS = self.fs
  51. def test_simple(self):
  52. fn = "bla"
  53. Lark(self.g, parser='lalr', cache=fn)
  54. assert fn in self.mock_fs.files
  55. parser = Lark(self.g, parser='lalr', cache=fn)
  56. assert parser.parse('a') == Tree('start', [])
  57. def test_automatic_naming(self):
  58. assert len(self.mock_fs.files) == 0
  59. Lark(self.g, parser='lalr', cache=True)
  60. assert len(self.mock_fs.files) == 1
  61. parser = Lark(self.g, parser='lalr', cache=True)
  62. assert parser.parse('a') == Tree('start', [])
  63. parser = Lark(self.g + ' "b"', parser='lalr', cache=True)
  64. assert len(self.mock_fs.files) == 2
  65. assert parser.parse('ab') == Tree('start', [])
  66. parser = Lark(self.g, parser='lalr', cache=True)
  67. assert parser.parse('a') == Tree('start', [])
  68. def test_custom_lexer(self):
  69. parser = Lark(self.g, parser='lalr', lexer=CustomLexer, cache=True)
  70. parser = Lark(self.g, parser='lalr', lexer=CustomLexer, cache=True)
  71. assert len(self.mock_fs.files) == 1
  72. assert parser.parse('a') == Tree('start', [])
  73. def test_options(self):
  74. # Test options persistence
  75. Lark(self.g, parser="lalr", debug=True, cache=True)
  76. parser = Lark(self.g, parser="lalr", debug=True, cache=True)
  77. assert parser.options.options['debug']
  78. def test_inline(self):
  79. # Test inline transformer (tree-less) & lexer_callbacks
  80. g = """
  81. start: add+
  82. add: NUM "+" NUM
  83. NUM: /\d+/
  84. %ignore " "
  85. """
  86. text = "1+2 3+4"
  87. expected = Tree('start', [30, 70])
  88. parser = Lark(g, parser='lalr', transformer=InlineTestT(), cache=True, lexer_callbacks={'NUM': append_zero})
  89. res0 = parser.parse(text)
  90. parser = Lark(g, parser='lalr', transformer=InlineTestT(), cache=True, lexer_callbacks={'NUM': append_zero})
  91. assert len(self.mock_fs.files) == 1
  92. res1 = parser.parse(text)
  93. res2 = InlineTestT().transform(Lark(g, parser="lalr", cache=True, lexer_callbacks={'NUM': append_zero}).parse(text))
  94. assert res0 == res1 == res2 == expected
  95. def test_imports(self):
  96. g = """
  97. %import .grammars.ab (startab, expr)
  98. """
  99. parser = Lark(g, parser='lalr', start='startab', cache=True, source_path=__file__)
  100. assert len(self.mock_fs.files) == 1
  101. parser = Lark(g, parser='lalr', start='startab', cache=True, source_path=__file__)
  102. assert len(self.mock_fs.files) == 1
  103. res = parser.parse("ab")
  104. self.assertEqual(res, Tree('startab', [Tree('expr', ['a', 'b'])]))
  105. if __name__ == '__main__':
  106. main()