summaryrefslogtreecommitdiff
path: root/plurals.jison
blob: 9364f994eb70ded2ba3d928176cba5660059965f (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
/* description: Parses end executes mathematical expressions. */

/* lexical grammar */
%lex
%%

\s+                   /* skip whitespace */
[0-9]+("."[0-9]+)?\b  return 'NUMBER'
"n"                   return 'n'
"||"                  return '||'
"&&"                  return '&&'
"?"                   return '?'
":"                   return ':'
"<="                  return '<='
">="                  return '>='
"<"                   return '<'
">"                   return '>'
"!="                  return '!='
"=="                  return '=='
"%"                   return '%'
"("                   return '('
")"                   return ')'
<<EOF>>               return 'EOF'
.                     return 'INVALID'

/lex

/* operator associations and precedence */

%right <code> '?' ':'
%left '||'
%left '&&'
%left '<=' '>=' '<' '>' '!=' '=='
%left '%'

%start expressions

%% /* language grammar */

expressions
    : e EOF
        { return { type : 'GROUP', expr: $1 }; }
    ;

e
    : e '?' e ':' e
        {$$ = { type: 'TERNARY', expr: $1, truthy : $3, falsey: $5 }; }
    | e '||' e
        {$$ = { type: "OR", left: $1, right: $3 };}
    | e '&&' e
        {$$ = { type: "AND", left: $1, right: $3 };}
    | e '<' e
        {$$ = { type: 'LT', left: $1, right: $3 }; }
    | e '<=' e
        {$$ = { type: 'LTE', left: $1, right: $3 };}
    | e '>' e
        {$$ = { type: 'GT', left: $1, right: $3 };}
    | e '>=' e
        {$$ = { type: 'GTE', left: $1, right: $3 };}
    | e '!=' e
        {$$ = { type: 'NEQ', left: $1, right: $3 };}
    | e '==' e
        {$$ = { type: 'EQ', left: $1, right: $3 };}
    | e '%' e
        {$$ = { type: 'MOD', left: $1, right: $3 };}
    | '(' e ')'
        {$$ = { type: 'GROUP', expr: $2 }; }
    | 'n'
        {$$ = { type: 'VAR' }; }
    | NUMBER
        {$$ = { type: 'NUM', val: Number(yytext) }; }
    ;