blob: 354a2e9d8b4bfa5a786f1faf614c7c3e950c0bde (
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
|
// Copyright 2021 Benjamin Barenblat
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
// The lexer and parser grammars for the EC language.
grammar Calculator;
options {
language = Cpp;
}
@parser::postinclude {
#include <stdexcept>
#include <string>
#include <utility>
#include "third_party/abseil/absl/strings/numbers.h"
}
program : term* ;
term : number | identifier | error ;
number returns [double value]
: s=NUMBER {
if (!absl::SimpleAtod($s->getText(), &$value)) {
throw std::runtime_error("Calculator: parser produced an invalid double");
}
}
;
identifier returns [std::string value]
: s=IDENTIFIER {
$value = std::move($s->getText());
}
| SUGARED_ADD { $value = "add"; }
| SUGARED_SUB { $value = "sub"; }
| SUGARED_MUL { $value = "mul"; }
| SUGARED_DIV { $value = "div"; }
;
error : ERROR ;
NUMBER : [+-]? (DIGIT+ '.'? DIGIT* | '.' DIGIT+) ('e' [+-]? DIGIT+)? ;
IDENTIFIER : [\p{Alpha}\p{General_Category=Other_Letter}] [\p{Alnum}\p{General_Category=Other_Letter}]* ;
SUGARED_ADD : '+' ;
SUGARED_SUB : '-' ;
SUGARED_MUL : '*' ;
SUGARED_DIV : '/' ;
WS : [\p{White_Space}]+ -> skip ;
ERROR : . ;
fragment DIGIT : [0-9] ;
|