From a4635fb95235ba4bf077bd59957da0626fc5ba72 Mon Sep 17 00:00:00 2001 From: Benjamin Barenblat Date: Tue, 14 Dec 2021 12:34:06 -0500 Subject: EC, a terminal-based RPN calculator --- src/Calculator.g4 | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 src/Calculator.g4 (limited to 'src/Calculator.g4') diff --git a/src/Calculator.g4 b/src/Calculator.g4 new file mode 100644 index 0000000..354a2e9 --- /dev/null +++ b/src/Calculator.g4 @@ -0,0 +1,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 +#include +#include + +#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] ; -- cgit v1.2.3