aboutsummaryrefslogtreecommitdiff
path: root/Source/Parser/wp_parser.y
blob: 809dbfa5e5584e3e589eb4a7fa83b2e62d6ea261 (plain) (blame)
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

%{
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    #include "wp_parser_y.h"
    int yylex (void);
%}

/* We do not need to make this reentrant safe, because we use flex and
   bison for generating AST only and this part doesn't need to be
   thread safe.
*/
/*%define api.pure full */

/* This is the type returned by functions wp_new* declared in
   wp_parser_y.h.  See also bison rules at the end of this file.
*/
%union {
    struct wp_node* n;
    amrex_real d;
    struct wp_symbol* s;
    enum wp_f1_t f1;
    enum wp_f2_t f2;
}

/* Define tokens.  They are used by flex too. */
%token <n>  NODE
%token <d>  NUMBER
%token <s>  SYMBOL
%token <f1> F1
%token <f2> F2
%token EOL
%token POW "**" '^'
%token GEQ ">="
%token LEQ "<="
%token EQ "=="
%token NEQ "!="
%token AND "and"
%token OR "or"

%nonassoc F1 F2
%right '='
%left OR
%left AND
%left EQ NEQ
%left '<' '>' GEQ LEQ
%left '+' '-'
%left '*' '/'
%nonassoc NEG UPLUS
%right POW

/* This specifies the type of `exp` (i.e., struct wp_node*).  Rules
   specified later pass `exp` to wp_new* functions declared in
   wp_parser_y.h.
*/
%type <n> exp

%start input

%%

/* Given `\n` terminated input, a tree is generated and passed to
 * function wp_defexpr defined in wp_parser_y.c.
 */
input:
  %empty
| input exp EOL {
    wp_defexpr($2);
  }
;

/* Enum types WP_ADD, WP_SUB, etc. are defined in wp_parser_y.h.
 * Functions wp_new* are also declared in that file.
 */
exp:
  NUMBER                     { $$ = wp_newnumber($1); }
| SYMBOL                     { $$ = wp_newsymbol($1); }
| exp '+' exp                { $$ = wp_newnode(WP_ADD, $1, $3); }
| exp '-' exp                { $$ = wp_newnode(WP_SUB, $1, $3); }
| exp '*' exp                { $$ = wp_newnode(WP_MUL, $1, $3); }
| exp '/' exp                { $$ = wp_newnode(WP_DIV, $1, $3); }
| '(' exp ')'                { $$ = $2; }
| exp '<' exp                { $$ = wp_newf2(WP_LT, $1, $3); }
| exp '>' exp                { $$ = wp_newf2(WP_GT, $1, $3); }
| exp LEQ exp                { $$ = wp_newf2(WP_LEQ, $1, $3); }
| exp GEQ exp                { $$ = wp_newf2(WP_GEQ, $1, $3); }
| exp EQ exp                 { $$ = wp_newf2(WP_EQ, $1, $3); }
| exp NEQ exp                { $$ = wp_newf2(WP_NEQ, $1, $3); }
| exp AND exp                { $$ = wp_newf2(WP_AND, $1, $3); }
| exp OR exp                 { $$ = wp_newf2(WP_OR, $1, $3); }
| '-'exp %prec NEG           { $$ = wp_newnode(WP_NEG, $2, NULL); }
| '+'exp %prec UPLUS         { $$ = $2; }
| exp POW exp                { $$ = wp_newf2(WP_POW, $1, $3); }
| F1 '(' exp ')'             { $$ = wp_newf1($1, $3); }
| F2 '(' exp ',' exp ')'     { $$ = wp_newf2($1, $3, $5); }
;

%%