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.

147 lines
3.4 KiB

  1. import json
  2. import unittest
  3. from unittest import TestCase
  4. from lark import Lark
  5. from lark.reconstruct import Reconstructor
  6. common = """
  7. %import common (WS_INLINE, NUMBER, WORD)
  8. %ignore WS_INLINE
  9. """
  10. def _remove_ws(s):
  11. return s.replace(' ', '').replace('\n','')
  12. class TestReconstructor(TestCase):
  13. def assert_reconstruct(self, grammar, code):
  14. parser = Lark(grammar, parser='lalr', maybe_placeholders=False)
  15. tree = parser.parse(code)
  16. new = Reconstructor(parser).reconstruct(tree)
  17. self.assertEqual(_remove_ws(code), _remove_ws(new))
  18. def test_starred_rule(self):
  19. g = """
  20. start: item*
  21. item: NL
  22. | rule
  23. rule: WORD ":" NUMBER
  24. NL: /(\\r?\\n)+\\s*/
  25. """ + common
  26. code = """
  27. Elephants: 12
  28. """
  29. self.assert_reconstruct(g, code)
  30. def test_starred_group(self):
  31. g = """
  32. start: (rule | NL)*
  33. rule: WORD ":" NUMBER
  34. NL: /(\\r?\\n)+\\s*/
  35. """ + common
  36. code = """
  37. Elephants: 12
  38. """
  39. self.assert_reconstruct(g, code)
  40. def test_alias(self):
  41. g = """
  42. start: line*
  43. line: NL
  44. | rule
  45. | "hello" -> hi
  46. rule: WORD ":" NUMBER
  47. NL: /(\\r?\\n)+\\s*/
  48. """ + common
  49. code = """
  50. Elephants: 12
  51. hello
  52. """
  53. self.assert_reconstruct(g, code)
  54. def test_keep_tokens(self):
  55. g = """
  56. start: (NL | stmt)*
  57. stmt: var op var
  58. !op: ("+" | "-" | "*" | "/")
  59. var: WORD
  60. NL: /(\\r?\\n)+\s*/
  61. """ + common
  62. code = """
  63. a+b
  64. """
  65. self.assert_reconstruct(g, code)
  66. @unittest.skip('Not working yet')
  67. def test_expand_rule(self):
  68. g = """
  69. ?start: (NL | mult_stmt)*
  70. ?mult_stmt: sum_stmt ["*" sum_stmt]
  71. ?sum_stmt: var ["+" var]
  72. var: WORD
  73. NL: /(\\r?\\n)+\s*/
  74. """ + common
  75. code = ['a', 'a*b', 'a+b', 'a*b+c', 'a+b*c', 'a+b*c+d']
  76. for c in code:
  77. self.assert_reconstruct(g, c)
  78. def test_json_example(self):
  79. test_json = '''
  80. {
  81. "empty_object" : {},
  82. "empty_array" : [],
  83. "booleans" : { "YES" : true, "NO" : false },
  84. "numbers" : [ 0, 1, -2, 3.3, 4.4e5, 6.6e-7 ],
  85. "strings" : [ "This", [ "And" , "That", "And a \\"b" ] ],
  86. "nothing" : null
  87. }
  88. '''
  89. json_grammar = r"""
  90. ?start: value
  91. ?value: object
  92. | array
  93. | string
  94. | SIGNED_NUMBER -> number
  95. | "true" -> true
  96. | "false" -> false
  97. | "null" -> null
  98. array : "[" [value ("," value)*] "]"
  99. object : "{" [pair ("," pair)*] "}"
  100. pair : string ":" value
  101. string : ESCAPED_STRING
  102. %import common.ESCAPED_STRING
  103. %import common.SIGNED_NUMBER
  104. %import common.WS
  105. %ignore WS
  106. """
  107. json_parser = Lark(json_grammar, parser='lalr', maybe_placeholders=False)
  108. tree = json_parser.parse(test_json)
  109. new_json = Reconstructor(json_parser).reconstruct(tree)
  110. self.assertEqual(json.loads(new_json), json.loads(test_json))
  111. if __name__ == '__main__':
  112. unittest.main()