-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcalculator.bnf
57 lines (52 loc) · 2.06 KB
/
calculator.bnf
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
/**
* Grammar rules for a four function calculator. The first step is defining the
* terminals of the grammar. These terminals represent the smallest unit of the
* language, such as a number or an operator, and are defined with the regular
* expression syntax. As an example, the following line defines a number whos
* string consists of one or more digits.
*
* 'num' [0-9]+;
*
* Grammar rules then define the valid combinations of these terminals in the
* user input. These rules are written as a nonterminal followed by zero or
* more symbols and ending with a semicolon. If there is more than one rule
* associated the same nonterminal, they are separated by a vertical bar. The
* following statement defines a multiplication to be either a number, or a
* previous product times a number.
*
* mult: 'num' | mult '*' 'num';
*
* Using the previous techniques for defining grammar rules, and implementing
* their associated functions, the following lists the full grammar of our
* calculator. The parser generator reads this grammar and outputs the source
* code of action tables. These action tables define which functions to call
* while the calculator is reading the input expressions. These action tables
* are then compiled along with the user defined functions to build a calculator
* program.
*/
#include "calculator.hpp"
/* Numbers and Identifiers */
'num'<Num> [0-9]+ &scan_num;
'hex'<Num> 0x([0-9]|[A-F]|[a-f])+ &scan_hex;
'exit'; /* declare exit first, so it's not an identifier */
'ident'<Ident> ([A-Z]|[a-z])+ &scan_ident;
/* Grammar Rules */
total<Num>: line &reduce_total
;
line<Num> : add &reduce_line
| 'ident' '=' add &reduce_assign
| 'exit' &reduce_exit
;
add<Num>: mul
| add '+' mul &reduce_add_mul
| add '-' mul &reduce_sub_mul
;
mul<Num>: int
| mul '*' int &reduce_mul_int
| mul '/' int &reduce_div_int
| '(' add ')' &reduce_paren
;
int<Num>: 'ident' &reduce_lookup
| 'num'
| 'hex'
;