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
3.8 KiB

  1. from __future__ import absolute_import, print_function
  2. import sys
  3. from unittest import TestCase, main
  4. from lark import Lark
  5. from lark.tree import Tree
  6. from lark.tools import standalone
  7. try:
  8. from StringIO import StringIO
  9. except ImportError:
  10. from io import StringIO
  11. class TestStandalone(TestCase):
  12. def setUp(self):
  13. pass
  14. def _create_standalone(self, grammar, compress=False):
  15. code_buf = StringIO()
  16. standalone.gen_standalone(Lark(grammar, parser='lalr'), out=code_buf, compress=compress)
  17. code = code_buf.getvalue()
  18. context = {'__doc__': None}
  19. exec(code, context)
  20. return context
  21. def test_simple(self):
  22. grammar = """
  23. start: NUMBER WORD
  24. %import common.NUMBER
  25. %import common.WORD
  26. %import common.WS
  27. %ignore WS
  28. """
  29. context = self._create_standalone(grammar)
  30. _Lark = context['Lark_StandAlone']
  31. l = _Lark()
  32. x = l.parse('12 elephants')
  33. self.assertEqual(x.children, ['12', 'elephants'])
  34. x = l.parse('16 candles')
  35. self.assertEqual(x.children, ['16', 'candles'])
  36. self.assertRaises(context['UnexpectedToken'], l.parse, 'twelve monkeys')
  37. self.assertRaises(context['UnexpectedToken'], l.parse, 'twelve')
  38. self.assertRaises(context['UnexpectedCharacters'], l.parse, '$ talks')
  39. context = self._create_standalone(grammar, compress=True)
  40. _Lark = context['Lark_StandAlone']
  41. l = _Lark()
  42. x = l.parse('12 elephants')
  43. def test_contextual(self):
  44. grammar = """
  45. start: a b
  46. a: "A" "B"
  47. b: "AB"
  48. """
  49. context = self._create_standalone(grammar)
  50. _Lark = context['Lark_StandAlone']
  51. l = _Lark()
  52. x = l.parse('ABAB')
  53. class T(context['Transformer']):
  54. def a(self, items):
  55. return 'a'
  56. def b(self, items):
  57. return 'b'
  58. start = list
  59. x = T().transform(x)
  60. self.assertEqual(x, ['a', 'b'])
  61. l2 = _Lark(transformer=T())
  62. x = l2.parse('ABAB')
  63. self.assertEqual(x, ['a', 'b'])
  64. def test_postlex(self):
  65. from lark.indenter import Indenter
  66. class MyIndenter(Indenter):
  67. NL_type = '_NEWLINE'
  68. OPEN_PAREN_types = ['LPAR', 'LSQB', 'LBRACE']
  69. CLOSE_PAREN_types = ['RPAR', 'RSQB', 'RBRACE']
  70. INDENT_type = '_INDENT'
  71. DEDENT_type = '_DEDENT'
  72. tab_len = 8
  73. grammar = r"""
  74. start: "(" ")" _NEWLINE
  75. _NEWLINE: /\n/
  76. """
  77. context = self._create_standalone(grammar)
  78. _Lark = context['Lark_StandAlone']
  79. l = _Lark(postlex=MyIndenter())
  80. x = l.parse('()\n')
  81. self.assertEqual(x, Tree('start', []))
  82. l = _Lark(postlex=MyIndenter())
  83. x = l.parse('(\n)\n')
  84. self.assertEqual(x, Tree('start', []))
  85. def test_transformer(self):
  86. grammar = r"""
  87. start: some_rule "(" SOME_TERMINAL ")"
  88. some_rule: SOME_TERMINAL
  89. SOME_TERMINAL: /[A-Za-z_][A-Za-z0-9_]*/
  90. """
  91. context = self._create_standalone(grammar)
  92. _Lark = context["Lark_StandAlone"]
  93. _Token = context["Token"]
  94. _Tree = context["Tree"]
  95. class MyTransformer(context["Transformer"]):
  96. def SOME_TERMINAL(self, token):
  97. return _Token("SOME_TERMINAL", "token is transformed")
  98. def some_rule(self, children):
  99. return _Tree("rule_is_transformed", [])
  100. parser = _Lark(transformer=MyTransformer())
  101. self.assertEqual(
  102. parser.parse("FOO(BAR)"),
  103. _Tree("start", [
  104. _Tree("rule_is_transformed", []),
  105. _Token("SOME_TERMINAL", "token is transformed")
  106. ])
  107. )
  108. if __name__ == '__main__':
  109. main()