Я бы хотел сделать что-то вроде этого:
// match used as a statement, semicolon is optional
match (1) {}
// match used as an expression, semicolon is required
1 + match (2) {};
statement
: expression_without_block T_SEMICOLON
| expression_with_block
;
expression
: expression_without_block
| expression_with_block
;
expression_without_block
: scalar
| expression_without_block T_PLUS expression
| T_PLUS expression
;
expression_with_block
: T_MATCH T_LEFT expression T_RIGHT T_CURLY_LEFT T_CURLY_RIGHT
;
Идея состоит в том, что expression_with_block
нельзя использовать в начале оператора, что делает однозначным следующее:
match (1) {}
+2;
// Can't mean
(match (1) {} + 2);
// because of the line "expression_without_block T_PLUS expression"
Грамматика вызывает конфликты сдвига / уменьшения, но я понятия не имею, почему. В выводе говорится следующее (но я не уверен, что с этим делать):
State 11 conflicts: 1 shift/reduce
...
State 11
5 expression: expression_without_block .
8 expression_without_block: expression_without_block . T_PLUS expression
T_PLUS shift, and go to state 14
T_PLUS [reduce using rule 5 (expression)]
$default reduce using rule 5 (expression)
Полный выходной файл можно найти здесь .
Я также даже не уверен, что это правильный подход, потому что тогда что-то вроде этого не сработает:
// `match` can't be at the lhs of an expression, even in sub-expressions
func_call(match (10) {} + 20);
Есть ли способ достичь того, что я описываю здесь, на зубрах? Я не эксперт по зубрам, поэтому буду очень признателен за помощь. Спасибо!
expr<NL>++
. Есть много других возможностей. - person rici   schedule 11.04.2020