summaryrefslogtreecommitdiff
path: root/scss/src/grammar/grammar.g
blob: 20c0a2f3e36b89c75f95c59ee1010e8507b1fb67 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# python yapps2.py grammar.g grammar.py

################################################################################
## Grammar compiled using Yapps:
%%
parser SassExpression:
    ignore: "[ \r\t\n]+"
    token COMMA: ","
    token LPAR: "\\(|\\["
    token RPAR: "\\)|\\]"
    token END: "$"
    token MUL: "[*]"
    token DIV: "/"
    token ADD: "[+]"
    token SUB: "-\s"
    token SIGN: "-(?![a-zA-Z_])"
    token AND: "(?<![-\w])and(?![-\w])"
    token OR: "(?<![-\w])or(?![-\w])"
    token NOT: "(?<![-\w])not(?![-\w])"
    token NE: "!="
    token INV: "!"
    token EQ: "=="
    token LE: "<="
    token GE: ">="
    token LT: "<"
    token GT: ">"
    token STR: "'[^']*'"
    token QSTR: '"[^"]*"'
    token UNITS: "(?<!\s)(?:[a-zA-Z]+|%)(?![-\w])"
    token NUM: "(?:\d+(?:\.\d*)?|\.\d+)"
    token COLOR: "#(?:[a-fA-F0-9]{6}|[a-fA-F0-9]{3})(?![a-fA-F0-9])"
    token VAR: "\$[-a-zA-Z0-9_]+"
    token FNCT: "[-a-zA-Z_][-a-zA-Z0-9_]*(?=\()"
    token ID: "!?[-a-zA-Z_][-a-zA-Z0-9_]*"
    token BANG_IMPORTANT: "!important"

    rule goal:          expr_lst END                {{ return expr_lst }}

    rule expr_lst:      expr_item                   {{ v = [expr_item] }}
                        (
                            COMMA [
                                expr_item           {{ v.append(expr_item) }}
                            ]                       {{ else: v.append((None, Literal(Undefined()))) }}
                        )*                          {{ return ListLiteral(v) if len(v) > 1 else v[0][1] }}

    rule expr_item:                                 {{ var = None }}
                        [
                            VAR [
                                ":"                 {{ var = VAR }}
                            ]                       {{ else: self._rewind() }}
                        ]
                        expr_slst                   {{ return (var, expr_slst) }}

    rule expr_slst:     or_expr                     {{ v = [(None, or_expr)] }}
                        (
                            or_expr                 {{ v.append((None, or_expr)) }}
                        )*                          {{ return ListLiteral(v, comma=False) if len(v) > 1 else v[0][1] }}

    rule or_expr:       and_expr                    {{ v = and_expr }}
                        (
                            OR and_expr             {{ v = AnyOp(v, and_expr) }}
                        )*                          {{ return v }}

    rule and_expr:      not_expr                    {{ v = not_expr }}
                        (
                            AND not_expr            {{ v = AllOp(v, not_expr) }}
                        )*                          {{ return v }}

    rule not_expr:      comparison                  {{ return comparison }}
                        | NOT not_expr              {{ return NotOp(not_expr) }}

    rule comparison:    a_expr                      {{ v = a_expr }}
                        (
                            LT a_expr               {{ v = BinaryOp(operator.lt, v, a_expr) }}
                            | GT a_expr             {{ v = BinaryOp(operator.gt, v, a_expr) }}
                            | LE a_expr             {{ v = BinaryOp(operator.le, v, a_expr) }}
                            | GE a_expr             {{ v = BinaryOp(operator.ge, v, a_expr) }}
                            | EQ a_expr             {{ v = BinaryOp(operator.eq, v, a_expr) }}
                            | NE a_expr             {{ v = BinaryOp(operator.ne, v, a_expr) }}
                        )*                          {{ return v }}

    rule a_expr:        m_expr                      {{ v = m_expr }}
                        (
                            ADD m_expr              {{ v = BinaryOp(operator.add, v, m_expr) }}
                            | SUB m_expr            {{ v = BinaryOp(operator.sub, v, m_expr) }}
                        )*                          {{ return v }}

    rule m_expr:        u_expr                      {{ v = u_expr }}
                        (
                            MUL u_expr              {{ v = BinaryOp(operator.mul, v, u_expr) }}
                            | DIV u_expr            {{ v = BinaryOp(operator.truediv, v, u_expr) }}
                        )*                          {{ return v }}

    rule u_expr:        SIGN u_expr                 {{ return UnaryOp(operator.neg, u_expr) }}
                        | ADD u_expr                {{ return UnaryOp(operator.pos, u_expr) }}
                        | atom                      {{ return atom }}

    rule atom:          ID                          {{ return Literal(parse_bareword(ID)) }}
                        | BANG_IMPORTANT            {{ return Literal(String(BANG_IMPORTANT, quotes=None)) }}
                        | LPAR                      {{ expr_lst = ListLiteral() }}
                            [ expr_lst ] RPAR       {{ return Parentheses(expr_lst) }}
                        | FNCT LPAR                 {{ expr_lst = ListLiteral() }}
                            [ expr_lst ] RPAR       {{ return CallOp(FNCT, expr_lst) }}
                        | NUM                       {{ UNITS = None }}
                            [ UNITS ]               {{ return Literal(NumberValue(float(NUM), unit=UNITS)) }}
                        | STR                       {{ return Literal(String(STR[1:-1], quotes="'")) }}
                        | QSTR                      {{ return Literal(String(QSTR[1:-1], quotes='"')) }}
                        | COLOR                     {{ return Literal(ColorValue(ParserValue(COLOR))) }}
                        | VAR                       {{ return Variable(VAR) }}
%%
### Grammar ends.
################################################################################