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.

140 lines
3.8 KiB

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