1# -*- coding: utf-8 -*-
2from __future__ import absolute_import
3
4import unittest
5import logging
6import os
7import codecs
8
9from lark import logger
10from lark.tools.nearley import create_code_for_nearley_grammar, main as nearley_tool_main
11
12logger.setLevel(logging.INFO)
13
14TEST_PATH    = os.path.abspath(os.path.dirname(__file__))
15NEARLEY_PATH = os.path.join(TEST_PATH, 'nearley')
16BUILTIN_PATH = os.path.join(NEARLEY_PATH, 'builtin')
17
18if not os.path.exists(NEARLEY_PATH):
19    logger.warn("Nearley not installed. Skipping Nearley tests!")
20    raise ImportError("Skipping Nearley tests!")
21
22import js2py    # Ensures that js2py exists, to avoid failing tests
23
24
25class TestNearley(unittest.TestCase):
26    def test_css(self):
27        fn = os.path.join(NEARLEY_PATH, 'examples/csscolor.ne')
28        with open(fn) as f:
29            grammar = f.read()
30
31        code = create_code_for_nearley_grammar(grammar, 'csscolor', BUILTIN_PATH, os.path.dirname(fn))
32        d = {}
33        exec (code, d)
34        parse = d['parse']
35
36        c = parse('#a199ff')
37        assert c['r'] == 161
38        assert c['g'] == 153
39        assert c['b'] == 255
40
41        c = parse('rgb(255, 70%, 3)')
42        assert c['r'] == 255
43        assert c['g'] == 178
44        assert c['b'] == 3
45
46    def test_include(self):
47        fn = os.path.join(NEARLEY_PATH, 'test/grammars/folder-test.ne')
48        with open(fn) as f:
49            grammar = f.read()
50
51        code = create_code_for_nearley_grammar(grammar, 'main', BUILTIN_PATH, os.path.dirname(fn))
52        d = {}
53        exec (code, d)
54        parse = d['parse']
55
56        parse('a')
57        parse('b')
58
59    def test_multi_include(self):
60        fn = os.path.join(NEARLEY_PATH, 'test/grammars/multi-include-test.ne')
61        with open(fn) as f:
62            grammar = f.read()
63
64        code = create_code_for_nearley_grammar(grammar, 'main', BUILTIN_PATH, os.path.dirname(fn))
65        d = {}
66        exec (code, d)
67        parse = d['parse']
68
69        parse('a')
70        parse('b')
71        parse('c')
72
73    def test_utf8(self):
74        grammar = u'main -> "±a"'
75        code = create_code_for_nearley_grammar(grammar, 'main', BUILTIN_PATH, './')
76        d = {}
77        exec (code, d)
78        parse = d['parse']
79
80        parse(u'±a')
81
82    def test_backslash(self):
83        grammar = r'main -> "\""'
84        code = create_code_for_nearley_grammar(grammar, 'main', BUILTIN_PATH, './')
85        d = {}
86        exec (code, d)
87        parse = d['parse']
88        parse(u'"')
89
90    def test_null(self):
91        grammar = r'main -> "a" | null'
92        code = create_code_for_nearley_grammar(grammar, 'main', BUILTIN_PATH, './')
93        d = {}
94        exec (code, d)
95        parse = d['parse']
96        parse('a')
97        parse('')
98
99    def test_utf8_2(self):
100        fn = os.path.join(TEST_PATH, 'grammars/unicode.ne')
101        nearley_tool_main(fn, 'x', NEARLEY_PATH)
102
103    def test_include_utf8(self):
104        fn = os.path.join(TEST_PATH, 'grammars/include_unicode.ne')
105        nearley_tool_main(fn, 'main', NEARLEY_PATH)
106
107
108if __name__ == '__main__':
109    unittest.main()
110