Replace {left,right}_assoc w/ prec, with an associativity argument

This commit is contained in:
Max Brunsfeld 2015-03-23 21:02:40 -07:00
parent a19b0e75ac
commit b1f8ba6202
7 changed files with 37 additions and 38 deletions

View file

@ -14,6 +14,11 @@ namespace rules {
class Rule;
typedef std::shared_ptr<Rule> rule_ptr;
enum Associativity {
AssociativityLeft = 1,
AssociativityRight
};
rule_ptr blank();
rule_ptr choice(const std::vector<rule_ptr> &);
rule_ptr repeat(const rule_ptr &);
@ -22,8 +27,8 @@ rule_ptr sym(const std::string &);
rule_ptr pattern(const std::string &);
rule_ptr str(const std::string &);
rule_ptr err(const rule_ptr &);
rule_ptr left_assoc(int precedence, const rule_ptr &);
rule_ptr right_assoc(int precedence, const rule_ptr &);
rule_ptr prec(int precedence, const rule_ptr &);
rule_ptr prec(int precedence, const rule_ptr &, Associativity);
rule_ptr token(const rule_ptr &rule);
std::ostream &operator<<(std::ostream &stream, const rules::rule_ptr &rule);

View file

@ -24,7 +24,7 @@ describe("expand_tokens", []() {
AssertThat(result.first.rules, Equals(rule_list({
{ "rule_A", seq({
i_sym(10),
token(left_assoc(1, seq({ character({ 'x' }), character({ 'y' }), character({ 'z' }) }))),
token(prec(1, seq({ character({ 'x' }), character({ 'y' }), character({ 'z' }) }))),
i_sym(11) }) },
})));
});
@ -38,7 +38,7 @@ describe("expand_tokens", []() {
auto result = expand_tokens(grammar);
AssertThat(result.first.rules, Equals(rule_list({
{ "rule_A", token(left_assoc(1, seq({
{ "rule_A", token(prec(1, seq({
character({ 945 }),
character({ ' ' }),
character({ 946 }) }))) }

View file

@ -146,7 +146,7 @@ extern const Grammar golang = Grammar({
infix_op(">=", "expression", 3),
infix_op(">", "expression", 3),
prefix_op("!", "expression", 4) }) },
{ "_func_signature", left_assoc(10, seq({
{ "_func_signature", prec(10, seq({
in_parens(comma_sep(seq({
comma_sep1(sym("var_name")),
sym("type_expression") }))),

View file

@ -29,20 +29,20 @@ rule_ptr in_brackets(rule_ptr rule) {
}
rule_ptr infix_op(std::string op, std::string rule_name, int precedence) {
return left_assoc(precedence, seq({
return prec(precedence, seq({
sym(rule_name),
str(op),
sym(rule_name) }));
}
rule_ptr prefix_op(std::string op, std::string rule_name, int precedence) {
return right_assoc(precedence, seq({
return prec(precedence, seq({
str(op),
sym(rule_name) }));
}
rule_ptr postfix_op(std::string op, std::string rule_name, int precedence) {
return left_assoc(precedence, seq({
return prec(precedence, seq({
sym(rule_name),
str(op) }));
}

View file

@ -65,16 +65,16 @@ extern const Grammar javascript = Grammar({
sym("identifier"),
sym("var_assignment") }))) })) },
{ "statement_block", left_assoc(PREC_BLOCK,
{ "statement_block", prec(PREC_BLOCK,
in_braces(err(repeat(sym("statement"))))) },
{ "if_statement", right_assoc(0, seq({
{ "if_statement", prec(0, seq({
str("if"),
sym("_paren_expression"),
sym("statement"),
optional(seq({
str("else"),
sym("statement") })) })) },
sym("statement") })) }), AssociativityRight) },
{ "switch_statement", seq({
str("switch"),
@ -99,7 +99,7 @@ extern const Grammar javascript = Grammar({
str("for"),
str("("),
optional(str("var")),
left_assoc(PREC_REL, seq({
prec(PREC_REL, seq({
sym("identifier"),
str("in"),
sym("expression") })),
@ -215,56 +215,56 @@ extern const Grammar javascript = Grammar({
str(")"),
sym("statement_block") }) },
{ "function_call", left_assoc(PREC_CALL, seq({
{ "function_call", prec(PREC_CALL, seq({
sym("expression"),
str("("),
optional(err(sym("arguments"))),
str(")") })) },
{ "constructor_call", choice({
left_assoc(PREC_SHORT_NEW, seq({
prec(PREC_SHORT_NEW, seq({
str("new"),
sym("expression") })),
left_assoc(PREC_FULL_NEW, seq({
prec(PREC_FULL_NEW, seq({
str("new"),
sym("expression"),
str("("),
err(optional(sym("arguments"))),
str(")") })) }) },
{ "member_access", left_assoc(PREC_MEMBER, seq({
{ "member_access", prec(PREC_MEMBER, seq({
sym("expression"),
str("."),
sym("identifier") })) },
{ "subscript_access", left_assoc(PREC_MEMBER, seq({
{ "subscript_access", prec(PREC_MEMBER, seq({
sym("expression"),
str("["),
err(sym("expression")),
str("]") })) },
{ "assignment", right_assoc(PREC_ASSIGN, seq({
{ "assignment", prec(PREC_ASSIGN, seq({
choice({
sym("identifier"),
sym("member_access"),
sym("subscript_access") }),
str("="),
sym("expression") })) },
sym("expression") }), AssociativityRight) },
{ "math_assignment", right_assoc(PREC_ASSIGN, seq({
{ "math_assignment", prec(PREC_ASSIGN, seq({
choice({
sym("identifier"),
sym("member_access"),
sym("subscript_access") }),
choice({ str("+="), str("-="), str("*="), str("/=") }),
sym("expression") })) },
sym("expression") }), AssociativityRight) },
{ "ternary", right_assoc(PREC_TERNARY, seq({
{ "ternary", prec(PREC_TERNARY, seq({
sym("expression"),
str("?"),
sym("expression"),
str(":"),
sym("expression") })) },
sym("expression") }), AssociativityRight) },
{ "bool_op", choice({
infix_op("||", "expression", PREC_OR),
@ -304,7 +304,7 @@ extern const Grammar javascript = Grammar({
infix_op(">", "expression", PREC_REL) }) },
{ "type_op", choice({
left_assoc(PREC_REL, seq({
prec(PREC_REL, seq({
choice({ sym("expression"), sym("identifier") }),
str("in"),
sym("expression") })),
@ -344,7 +344,7 @@ extern const Grammar javascript = Grammar({
{ "formal_parameters", comma_sep1(sym("identifier")) },
{ "arguments", left_assoc(-5, comma_sep1(err(sym("expression")))) },
{ "arguments", prec(-5, comma_sep1(err(sym("expression")))) },
{ "pair", seq({
choice({ sym("string"), sym("identifier") }),

View file

@ -3,6 +3,7 @@
#include <string>
#include <map>
#include "tree_sitter/compiler.h"
#include "compiler/rules/rule.h"
namespace tree_sitter {
@ -16,11 +17,7 @@ enum MetadataKey {
ASSOCIATIVITY,
};
enum Associativity {
AssociativityUnspecified,
AssociativityLeft,
AssociativityRight,
};
const Associativity AssociativityUnspecified = (Associativity)0;
class Metadata : public Rule {
public:

View file

@ -43,25 +43,22 @@ rule_ptr sym(const string &name) { return make_shared<NamedSymbol>(name); }
rule_ptr pattern(const string &value) { return make_shared<Pattern>(value); }
rule_ptr str(const string &value) {
return token(left_assoc(1, make_shared<String>(value)));
return token(prec(1, make_shared<String>(value)));
}
rule_ptr err(const rule_ptr &rule) {
return choice({ rule, ERROR().copy() });
}
rule_ptr left_assoc(int precedence, const rule_ptr &rule) {
rule_ptr prec(int precedence, const rule_ptr &rule, Associativity associativity) {
return metadata(rule, {
{ PRECEDENCE, precedence },
{ ASSOCIATIVITY, AssociativityLeft }
{ ASSOCIATIVITY, associativity }
});
}
rule_ptr right_assoc(int precedence, const rule_ptr &rule) {
return metadata(rule, {
{ PRECEDENCE, precedence },
{ ASSOCIATIVITY, AssociativityRight }
});
rule_ptr prec(int precedence, const rule_ptr &rule) {
return prec(precedence, rule, AssociativityLeft);
}
rule_ptr token(const rule_ptr &rule) {