This repo contains code to mirror other repos. It also contains the code that is getting mirrored.
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

146 行
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. def test_expand_rule(self):
  67. g = """
  68. ?start: (NL | mult_stmt)*
  69. ?mult_stmt: sum_stmt ["*" sum_stmt]
  70. ?sum_stmt: var ["+" var]
  71. var: WORD
  72. NL: /(\\r?\\n)+\s*/
  73. """ + common
  74. code = ['a', 'a*b', 'a+b', 'a*b+c', 'a+b*c', 'a+b*c+d']
  75. for c in code:
  76. self.assert_reconstruct(g, c)
  77. def test_json_example(self):
  78. test_json = '''
  79. {
  80. "empty_object" : {},
  81. "empty_array" : [],
  82. "booleans" : { "YES" : true, "NO" : false },
  83. "numbers" : [ 0, 1, -2, 3.3, 4.4e5, 6.6e-7 ],
  84. "strings" : [ "This", [ "And" , "That", "And a \\"b" ] ],
  85. "nothing" : null
  86. }
  87. '''
  88. json_grammar = r"""
  89. ?start: value
  90. ?value: object
  91. | array
  92. | string
  93. | SIGNED_NUMBER -> number
  94. | "true" -> true
  95. | "false" -> false
  96. | "null" -> null
  97. array : "[" [value ("," value)*] "]"
  98. object : "{" [pair ("," pair)*] "}"
  99. pair : string ":" value
  100. string : ESCAPED_STRING
  101. %import common.ESCAPED_STRING
  102. %import common.SIGNED_NUMBER
  103. %import common.WS
  104. %ignore WS
  105. """
  106. json_parser = Lark(json_grammar, parser='lalr', maybe_placeholders=False)
  107. tree = json_parser.parse(test_json)
  108. new_json = Reconstructor(json_parser).reconstruct(tree)
  109. self.assertEqual(json.loads(new_json), json.loads(test_json))
  110. if __name__ == '__main__':
  111. unittest.main()