// Copyright 2018 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "src/torque/earley-parser.h" #include "test/unittests/test-utils.h" namespace v8 { namespace internal { namespace torque { namespace { template base::Optional MakeBinop(ParseResultIterator* child_results) { // Ideally, we would want to use int as a result type here instead of // std::string. This is possible, but requires adding int to the list of // supported ParseResult types in torque-parser.cc. To avoid changing that // code, we use std::string here, which is already used in the Torque parser. auto a = child_results->NextAs(); auto b = child_results->NextAs(); return ParseResult{std::to_string(op(std::stoi(a), std::stoi(b)))}; } int plus(int a, int b) { return a + b; } int minus(int a, int b) { return a - b; } int mul(int a, int b) { return a * b; } } // namespace struct SimpleArithmeticGrammar : Grammar { static bool MatchWhitespace(InputPosition* pos) { while (MatchChar(std::isspace, pos)) { } return true; } static bool MatchInteger(InputPosition* pos) { InputPosition current = *pos; MatchString("-", ¤t); if (MatchChar(std::isdigit, ¤t)) { while (MatchChar(std::isdigit, ¤t)) { } *pos = current; return true; } return false; } SimpleArithmeticGrammar() : Grammar(&sum_expression) { SetWhitespace(MatchWhitespace); } Symbol integer = {Rule({Pattern(MatchInteger)}, YieldMatchedInput)}; Symbol atomic_expression = {Rule({&integer}), Rule({Token("("), &sum_expression, Token(")")})}; Symbol mul_expression = { Rule({&atomic_expression}), Rule({&mul_expression, Token("*"), &atomic_expression}, MakeBinop)}; Symbol sum_expression = { Rule({&mul_expression}), Rule({&sum_expression, Token("+"), &mul_expression}, MakeBinop), Rule({&sum_expression, Token("-"), &mul_expression}, MakeBinop)}; }; TEST(EarleyParser, SimpleArithmetic) { SimpleArithmeticGrammar grammar; SourceFileMap::Scope source_file_map; CurrentSourceFile::Scope current_source_file{ SourceFileMap::AddSource("dummy_filename")}; std::string result1 = grammar.Parse("-5 - 5 + (3 + 5) * 2")->Cast(); ASSERT_EQ("6", result1); std::string result2 = grammar.Parse("((-1 + (1) * 2 + 3 - 4 * 5 + -6 * 7))") ->Cast(); ASSERT_EQ("-58", result2); } } // namespace torque } // namespace internal } // namespace v8