Add operator precedence parser. (#464)

This commit is contained in:
Richard Smith
2021-04-15 18:23:36 -07:00
committed by GitHub
parent 82d5a25caa
commit 09763653b7
9 changed files with 656 additions and 6 deletions
+76
View File
@@ -408,6 +408,82 @@ TEST_F(ParseTreeTest, InvalidDesignators) {
MatchFileEnd()}));
}
TEST_F(ParseTreeTest, Operators) {
TokenizedBuffer tokens = GetTokenizedBuffer(
"fn F() {\n"
" n = a * b + c * d = d * d << e & f - not g;\n"
" ++++n;\n"
" n++++;\n"
" a and b and c;\n"
" a and b or c;\n"
" a or b and c;\n"
" not a and not b and not c;\n"
"}");
ParseTree tree = ParseTree::Parse(tokens, consumer);
EXPECT_TRUE(tree.HasErrors());
EXPECT_THAT(
tree,
MatchParseTreeNodes(
{MatchFunctionDeclaration(
MatchDeclaredName("F"),
MatchParameterList(MatchParameterListEnd()),
MatchCodeBlock(
MatchExpressionStatement(MatchInfixOperator(
MatchNameReference("n"), "=",
MatchInfixOperator(
MatchInfixOperator(
MatchInfixOperator(MatchNameReference("a"), "*",
MatchNameReference("b")),
"+",
MatchInfixOperator(MatchNameReference("c"), "*",
MatchNameReference("d"))),
"=",
MatchInfixOperator(
HasError,
MatchInfixOperator(
HasError,
MatchInfixOperator(
HasError,
MatchInfixOperator(
MatchNameReference("d"), "*",
MatchNameReference("d")),
"<<", MatchNameReference("e")),
"&", MatchNameReference("f")),
"-",
MatchPrefixOperator("not",
MatchNameReference("g")))))),
MatchExpressionStatement(MatchPrefixOperator(
"++",
MatchPrefixOperator("++", MatchNameReference("n")))),
MatchExpressionStatement(MatchPostfixOperator(
MatchPostfixOperator(MatchNameReference("n"), "++"),
"++")),
MatchExpressionStatement(MatchInfixOperator(
MatchInfixOperator(MatchNameReference("a"), "and",
MatchNameReference("b")),
"and", MatchNameReference("c"))),
MatchExpressionStatement(MatchInfixOperator(
HasError,
MatchInfixOperator(MatchNameReference("a"), "and",
MatchNameReference("b")),
"or", MatchNameReference("c"))),
MatchExpressionStatement(MatchInfixOperator(
HasError,
MatchInfixOperator(MatchNameReference("a"), "or",
MatchNameReference("b")),
"and", MatchNameReference("c"))),
MatchExpressionStatement(MatchInfixOperator(
MatchInfixOperator(
MatchPrefixOperator("not", MatchNameReference("a")),
"and",
MatchPrefixOperator("not", MatchNameReference("b"))),
"and",
MatchPrefixOperator("not", MatchNameReference("c")))),
MatchCodeBlockEnd())),
MatchFileEnd()}));
}
auto GetAndDropLine(llvm::StringRef& s) -> std::string {
auto newline_offset = s.find_first_of('\n');
llvm::StringRef line = s.slice(0, newline_offset);