-
Notifications
You must be signed in to change notification settings - Fork 89
/
Copy pathcalc-ast-java.bnf
132 lines (101 loc) · 2.59 KB
/
calc-ast-java.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
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/**
* Generated parser in Java.
*
* ./bin/syntax -g examples/calc.java.g -m lalr1 -o CalcParser.rs
*
* import com.syntax.*;
*
* CalcParser parser = new CalcParser();
*
* System.out.println(parser.parse("2 + 2 * 2");
* System.out.println(parser.parse("(2 + 2) * 2");
*/
// -----------------------------------------------------------------------------
// Lexical grammar
/**
* RegExp-based lexical grammar. Simple symbols like '*', '(', etc, can be
* defined inline.
*/
%lex
%%
\s+ /* skip whitespace */ return null
\d+ return "NUMBER"
/lex
// -----------------------------------------------------------------------------
// Operator precedence
/**
* Both, '+' and '*' are left-associative. I.e. 5 + 3 + 2 is parsed as
* (5 + 3) + 2, and not as 5 + (3 + 2).
*
* The '*' goes after '+' in the list below, so it has higher precedence,
* and 2 + 2 * 2 is parsed as correctly as 2 + (2 * 2).
*/
%left '+'
%left '*'
// -----------------------------------------------------------------------------
// Module include
/**
* The code in the module include section is included "as is".
* If can contain the `ParserEvents` class, which defines parse even handlers.
*/
%{
/**
* The ParserEvents class allows subscribing to
* different parsing events.
*/
class ParserEvents {
public static void init() {
System.out.println("Parser is created.");
}
public static void onParseBegin(String str) {
System.out.println("Parsing is started: " + str);
}
public static void onParseEnd(Object result) {
System.out.println("Parsing is completed: " + result);
}
}
// Define the class nodes inline here, however on practice they can be
// located anywhere, and just imported here.
class Node {
public String type;
}
class BinaryNode extends Node {
public Node left;
public Node right;
public String operator;
public BinaryNode(Object left, Object op, Object right) {
this.type = "BinaryNode";
this.left = (Node)left;
this.right = (Node)right;
this.operator = (String)op;
}
}
class LiteralNode extends Node {
public Integer value;
public LiteralNode(Integer value) {
this.type = "LiteralNode";
this.value = value;
}
}
%}
// -----------------------------------------------------------------------------
// Syntactic grammar (BNF)
%%
Expression
: Expression '+' Expression
{
$$ = new BinaryNode($1, $2, $3)
}
| Expression '*' Expression
{
$$ = new BinaryNode($1, $2, $3)
}
| NUMBER
{
$$ = new LiteralNode(Integer.valueOf(yytext))
}
| '(' Expression ')'
{
$$ = $2
}
;