mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-30 06:35:01 +01:00
Support parsing and testing unimplemented expressions (#957)
Co-authored-by: Jon Meow <46229924+jonmeow@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
co-authored by
Jon Meow
parent
be0c1e9da6
commit
dc5e62fc7a
@@ -22,6 +22,17 @@ cc_test(
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "parse_test_matchers",
|
||||
testonly = 1,
|
||||
srcs = ["parse_test_matchers_internal.h"],
|
||||
hdrs = ["parse_test_matchers.h"],
|
||||
deps = [
|
||||
":syntax",
|
||||
"@com_google_googletest//:gtest",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "syntax",
|
||||
srcs = [
|
||||
@@ -108,3 +119,14 @@ mypy_test(
|
||||
include_imports = True,
|
||||
deps = [":format_grammar_lib"],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "unimplemented_example_test",
|
||||
srcs = ["unimplemented_example_test.cpp"],
|
||||
deps = [
|
||||
":parse_test_matchers",
|
||||
":syntax",
|
||||
"//executable_semantics/ast:ast_test_matchers",
|
||||
"@com_google_googletest//:gtest_main",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -77,6 +77,7 @@ STRING "String"
|
||||
TRUE "true"
|
||||
TYPE "Type"
|
||||
UNDERSCORE "_"
|
||||
UNIMPL_EXAMPLE "__unimplemented_example_infix"
|
||||
VAR "var"
|
||||
WHILE "while"
|
||||
/* table-end */
|
||||
@@ -169,6 +170,7 @@ string_literal \"([^\\\"\n\v\f\r]|\\.)*\"
|
||||
{TRUE} { return SIMPLE_TOKEN(TRUE); }
|
||||
{TYPE} { return SIMPLE_TOKEN(TYPE); }
|
||||
{UNDERSCORE} { return SIMPLE_TOKEN(UNDERSCORE); }
|
||||
{UNIMPL_EXAMPLE} { return SIMPLE_TOKEN(UNIMPL_EXAMPLE); }
|
||||
{VAR} { return SIMPLE_TOKEN(VAR); }
|
||||
{WHILE} { return SIMPLE_TOKEN(WHILE); }
|
||||
/* table-end */
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
||||
// Exceptions. See /LICENSE for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
#ifndef EXECUTABLE_SEMANTICS_SYNTAX_PARSE_TEST_MATCHERS_H_
|
||||
#define EXECUTABLE_SEMANTICS_SYNTAX_PARSE_TEST_MATCHERS_H_
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "executable_semantics/syntax/parse_test_matchers_internal.h"
|
||||
|
||||
namespace Carbon {
|
||||
|
||||
// Matches the return value of `Parse()` if it represents a successful parse
|
||||
// whose output matches the given matcher.
|
||||
inline auto ParsedAs(::testing::Matcher<AST> ast_matcher) {
|
||||
return TestingInternal::ParsedAsMatcher(std::move(ast_matcher));
|
||||
}
|
||||
|
||||
} // namespace Carbon
|
||||
|
||||
#endif // EXECUTABLE_SEMANTICS_SYNTAX_PARSE_TEST_MATCHERS_H_
|
||||
@@ -0,0 +1,59 @@
|
||||
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
||||
// Exceptions. See /LICENSE for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
#ifndef EXECUTABLE_SEMANTICS_SYNTAX_PARSE_TEST_MATCHERS_INTERNAL_H_
|
||||
#define EXECUTABLE_SEMANTICS_SYNTAX_PARSE_TEST_MATCHERS_INTERNAL_H_
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <ostream>
|
||||
#include <variant>
|
||||
|
||||
#include "executable_semantics/syntax/parse.h"
|
||||
|
||||
namespace Carbon {
|
||||
namespace TestingInternal {
|
||||
|
||||
// Implementation of ParsedAs(). See there for detailed documentation.
|
||||
class ParsedAsMatcher {
|
||||
public:
|
||||
using is_gtest_matcher = void;
|
||||
|
||||
explicit ParsedAsMatcher(::testing::Matcher<AST> ast_matcher)
|
||||
: ast_matcher_(std::move(ast_matcher)) {}
|
||||
|
||||
void DescribeTo(std::ostream* out) const {
|
||||
DescribeToImpl(out, /*negated=*/false);
|
||||
}
|
||||
|
||||
void DescribeNegationTo(std::ostream* out) const {
|
||||
DescribeToImpl(out, /*negated=*/true);
|
||||
}
|
||||
|
||||
auto MatchAndExplain(const std::variant<AST, SyntaxErrorCode>& result,
|
||||
::testing::MatchResultListener* listener) const -> bool {
|
||||
if (std::holds_alternative<SyntaxErrorCode>(result)) {
|
||||
*listener << "holds error code " << std::get<SyntaxErrorCode>(result);
|
||||
return false;
|
||||
} else {
|
||||
*listener << "is a successful parse whose ";
|
||||
return ast_matcher_.MatchAndExplain(std::get<AST>(result), listener);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void DescribeToImpl(std::ostream* out, bool negated) const {
|
||||
*out << "is " << (negated ? "not " : "")
|
||||
<< "a successful parse result whose ";
|
||||
ast_matcher_.DescribeTo(out);
|
||||
}
|
||||
|
||||
::testing::Matcher<AST> ast_matcher_;
|
||||
};
|
||||
|
||||
} // namespace TestingInternal
|
||||
} // namespace Carbon
|
||||
|
||||
#endif // EXECUTABLE_SEMANTICS_SYNTAX_PARSE_TEST_MATCHERS_INTERNAL_H_
|
||||
@@ -190,6 +190,7 @@
|
||||
TRUE
|
||||
TYPE
|
||||
UNDERSCORE
|
||||
UNIMPL_EXAMPLE
|
||||
VAR
|
||||
WHILE
|
||||
// table-end
|
||||
@@ -223,6 +224,7 @@
|
||||
// same precedence as POSTFIX_STAR.
|
||||
%precedence POSTFIX_STAR UNARY_STAR
|
||||
%left PERIOD ARROW
|
||||
%nonassoc UNIMPL_EXAMPLE
|
||||
%precedence
|
||||
LEFT_PARENTHESIS
|
||||
RIGHT_PARENTHESIS
|
||||
@@ -381,6 +383,11 @@ expression:
|
||||
}
|
||||
| FN_TYPE tuple ARROW expression
|
||||
{ $$ = arena->New<FunctionTypeLiteral>(context.source_loc(), $2, $4); }
|
||||
| expression UNIMPL_EXAMPLE expression
|
||||
{
|
||||
$$ = arena->New<UnimplementedExpression>(context.source_loc(),
|
||||
"ExampleInfix", $1, $3);
|
||||
}
|
||||
;
|
||||
designator: PERIOD identifier { $$ = $2; }
|
||||
;
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
||||
// Exceptions. See /LICENSE for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "executable_semantics/ast/ast_test_matchers.h"
|
||||
#include "executable_semantics/syntax/parse.h"
|
||||
#include "executable_semantics/syntax/parse_test_matchers.h"
|
||||
|
||||
namespace Carbon {
|
||||
namespace {
|
||||
|
||||
using ::testing::ElementsAre;
|
||||
|
||||
TEST(UnimplementedExampleTest, VerifyPrecedence) {
|
||||
static constexpr std::string_view Program = R"(
|
||||
package ExecutableSemanticsTest api;
|
||||
fn Main() -> i32 {
|
||||
return 1 __unimplemented_example_infix 2 + 3;
|
||||
}
|
||||
)";
|
||||
Arena arena;
|
||||
EXPECT_THAT(ParseFromString(&arena, "dummy.carbon", Program, false),
|
||||
ParsedAs(ASTDeclarations(
|
||||
ElementsAre(MatchesFunctionDeclaration().WithBody(
|
||||
BlockContentsAre(ElementsAre(MatchesReturn(MatchesAdd(
|
||||
MatchesUnimplementedExpression(
|
||||
"ExampleInfix", ElementsAre(MatchesLiteral(1),
|
||||
MatchesLiteral(2))),
|
||||
MatchesLiteral(3))))))))));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace Carbon
|
||||
Reference in New Issue
Block a user