437f680e19
TBR: yangguo@chromium.org Bug: v8:7793 Change-Id: Ie680d72a1da23038d3136f82532496eabbd9c363 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1632227 Commit-Queue: Tobias Tebbi <tebbi@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Reviewed-by: Sigurd Schneider <sigurds@chromium.org> Cr-Commit-Position: refs/heads/master@{#62004}
85 lines
2.6 KiB
C++
85 lines
2.6 KiB
C++
// 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 <int op(int, int)>
|
|
base::Optional<ParseResult> 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<std::string>();
|
|
auto b = child_results->NextAs<std::string>();
|
|
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<mul>)};
|
|
|
|
Symbol sum_expression = {
|
|
Rule({&mul_expression}),
|
|
Rule({&sum_expression, Token("+"), &mul_expression}, MakeBinop<plus>),
|
|
Rule({&sum_expression, Token("-"), &mul_expression}, MakeBinop<minus>)};
|
|
};
|
|
|
|
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<std::string>();
|
|
ASSERT_EQ("6", result1);
|
|
std::string result2 = grammar.Parse("((-1 + (1) * 2 + 3 - 4 * 5 + -6 * 7))")
|
|
->Cast<std::string>();
|
|
ASSERT_EQ("-58", result2);
|
|
}
|
|
|
|
} // namespace torque
|
|
} // namespace internal
|
|
} // namespace v8
|