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.

138 lines
3.7 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):
  15. code_buf = StringIO()
  16. standalone.gen_standalone(Lark(grammar, parser='lalr'), out=code_buf)
  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. def test_contextual(self):
  40. grammar = """
  41. start: a b
  42. a: "A" "B"
  43. b: "AB"
  44. """
  45. context = self._create_standalone(grammar)
  46. _Lark = context['Lark_StandAlone']
  47. l = _Lark()
  48. x = l.parse('ABAB')
  49. class T(context['Transformer']):
  50. def a(self, items):
  51. return 'a'
  52. def b(self, items):
  53. return 'b'
  54. start = list
  55. x = T().transform(x)
  56. self.assertEqual(x, ['a', 'b'])
  57. l2 = _Lark(transformer=T())
  58. x = l2.parse('ABAB')
  59. self.assertEqual(x, ['a', 'b'])
  60. def test_postlex(self):
  61. from lark.indenter import Indenter
  62. class MyIndenter(Indenter):
  63. NL_type = '_NEWLINE'
  64. OPEN_PAREN_types = ['LPAR', 'LSQB', 'LBRACE']
  65. CLOSE_PAREN_types = ['RPAR', 'RSQB', 'RBRACE']
  66. INDENT_type = '_INDENT'
  67. DEDENT_type = '_DEDENT'
  68. tab_len = 8
  69. grammar = r"""
  70. start: "(" ")" _NEWLINE
  71. _NEWLINE: /\n/
  72. """
  73. context = self._create_standalone(grammar)
  74. _Lark = context['Lark_StandAlone']
  75. l = _Lark(postlex=MyIndenter())
  76. x = l.parse('()\n')
  77. self.assertEqual(x, Tree('start', []))
  78. l = _Lark(postlex=MyIndenter())
  79. x = l.parse('(\n)\n')
  80. self.assertEqual(x, Tree('start', []))
  81. def test_transformer(self):
  82. grammar = r"""
  83. start: some_rule "(" SOME_TERMINAL ")"
  84. some_rule: SOME_TERMINAL
  85. SOME_TERMINAL: /[A-Za-z_][A-Za-z0-9_]*/
  86. """
  87. context = self._create_standalone(grammar)
  88. _Lark = context["Lark_StandAlone"]
  89. _Token = context["Token"]
  90. _Tree = context["Tree"]
  91. class MyTransformer(context["Transformer"]):
  92. def SOME_TERMINAL(self, token):
  93. return _Token("SOME_TERMINAL", "token is transformed")
  94. def some_rule(self, children):
  95. return _Tree("rule_is_transformed", [])
  96. parser = _Lark(transformer=MyTransformer())
  97. self.assertEqual(
  98. parser.parse("FOO(BAR)"),
  99. _Tree("start", [
  100. _Tree("rule_is_transformed", []),
  101. _Token("SOME_TERMINAL", "token is transformed")
  102. ])
  103. )
  104. if __name__ == '__main__':
  105. main()