1# -*- coding: utf-8 -*-
2"""
3    Basic Grammar Notation Tests
4    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5
6    :copyright: Copyright 2006-2020 by the Pygments team, see AUTHORS.
7    :license: BSD, see LICENSE for details.
8"""
9
10import pytest
11
12from pygments.token import Token
13from pygments.lexers import PegLexer
14
15
16@pytest.fixture(scope='module')
17def lexer_peg():
18    yield PegLexer()
19
20
21def test_peg_basic(lexer_peg):
22    fragment = 'rule<-("terminal"/nonterminal/[cls])*\n'
23    tokens = [
24        (Token.Name.Class, 'rule'),
25        (Token.Operator, '<-'),
26        (Token.Punctuation, '('),
27        (Token.String.Double, '"terminal"'),
28        (Token.Operator, '/'),
29        (Token.Name.Class, 'nonterminal'),
30        (Token.Operator, '/'),
31        (Token.Punctuation, '['),
32        (Token.String, 'cls'),
33        (Token.Punctuation, ']'),
34        (Token.Punctuation, ')'),
35        (Token.Operator, '*'),
36        (Token.Text, '\n'),
37    ]
38    assert list(lexer_peg.get_tokens(fragment)) == tokens
39
40
41def test_peg_operators(lexer_peg):
42    # see for example:
43    # - https://github.com/gvanrossum/pegen
44    # - https://nim-lang.org/docs/pegs.html
45    fragment = "rule = 'a' | 'b'\n"
46    tokens = [
47        (Token.Name.Class, 'rule'),
48        (Token.Text, ' '),
49        (Token.Operator, '='),
50        (Token.Text, ' '),
51        (Token.String.Single, "'a'"),
52        (Token.Text, ' '),
53        (Token.Operator, '|'),
54        (Token.Text, ' '),
55        (Token.String.Single, "'b'"),
56        (Token.Text, '\n'),
57    ]
58    assert list(lexer_peg.get_tokens(fragment)) == tokens
59    fragment = "rule: 'a' ~ 'b'\n"
60    tokens = [
61        (Token.Name.Class, 'rule'),
62        (Token.Operator, ':'),
63        (Token.Text, ' '),
64        (Token.String.Single, "'a'"),
65        (Token.Text, ' '),
66        (Token.Operator, '~'),
67        (Token.Text, ' '),
68        (Token.String.Single, "'b'"),
69        (Token.Text, '\n'),
70    ]
71    assert list(lexer_peg.get_tokens(fragment)) == tokens
72
73
74def test_peg_modified_strings(lexer_peg):
75    # see for example:
76    # - http://textx.github.io/Arpeggio/
77    # - https://nim-lang.org/docs/pegs.html
78    # - https://github.com/erikrose/parsimonious
79    fragment = '~"regex" i"insensitive" "multimod"ilx ("not modified")\n'
80    tokens = [
81        # can't handle parsimonious-style regex while ~ is a cut operator
82        (Token.Operator, '~'),
83        (Token.String.Double, '"regex"'),
84        (Token.Text, ' '),
85        (Token.String.Double, 'i"insensitive"'),
86        (Token.Text, ' '),
87        (Token.String.Double, '"multimod"ilx'),
88        (Token.Text, ' '),
89        (Token.Punctuation, '('),
90        (Token.String.Double, '"not modified"'),
91        (Token.Punctuation, ')'),
92        (Token.Text, '\n'),
93    ]
94    assert list(lexer_peg.get_tokens(fragment)) == tokens
95