Счастливое определение функции приоритета и переменная
Я изо всех сил пытался удалить все конфликты s/r из моего парсера сегодня. Мне удалось удалить их всех, кроме одного.
Синтаксис моего языка должен быть похож на haskell. И вместо main
У меня есть выражение верхнего уровня, которое является записью.
Парсер показан ниже. Я также добавил выдержку из Parser.info
файл, который генерирует Happy, в котором он описывает сдвиг / уменьшение конфликтов.
Насколько я могу судить, проблема в том, что когда varname
для определения функции может потребоваться две ветви. Можно предположить, что есть больше varname
s, потому что он в настоящее время анализирует определение функции (у которого есть один или несколько параметров), или он может прекратить анализировать ее как выражение переменной. Возможный varname
после этого просто другое выражение.
Я играл с %prec
правила и ничто не помогло.
Моим первым рассуждением было то, что, учитывая, что парсер хочет перейти к определению функции, я могу дать этому правилу приоритет. Я также попытался добавить приоритет к =
оператор (для определения функции), так что я мог поставить его под приоритет определения функции, но это тоже не сработало. Я думаю, что я не совсем понимаю, как работают парсеры. Любые указатели очень ценятся.
Небольшое замечание: поведение по умолчанию - то, что я считаю, таким образом, сдвиг - также является желаемым поведением.
state 25 contains 1 shift/reduce conflicts.
...
State 25
Definition -> varname . ':' ':' Type (rule 7)
Definition -> varname . FunctionParameters '=' Exp bl (rule 8)
Atom -> varname . (rule 20)
'(' reduce using rule 20
'<' reduce using rule 20
'>' reduce using rule 20
'/' reduce using rule 20
'*' reduce using rule 20
'-' reduce using rule 20
'+' reduce using rule 20
"eq?" reduce using rule 20
number reduce using rule 20
':' shift, and enter state 27
varname shift, and enter state 28
(reduce using rule 20)
%eof reduce using rule 20
FunctionParametersgoto state 26
синтаксический анализатор
%nonassoc PARS
%nonassoc VAR
%%
Program
: Definitions Exp { Program $1 $2 }
| Exp { Program [] $1 }
Definitions
: Definitions Definition { ($1 ++ [$2]) }
| Definition { [$1] }
Definition
: type upsym '=' Type { TypeDef $2 $4 }
| varname ':' ':' Type { FTypeDef $1 $4 }
| varname FunctionParameters '=' Exp bl { FDef $1 $2 $4 }
FunctionParameters
: FunctionParameters varname %prec PARS { $1 ++ [$2] }
| varname { [$1] }
Exp
: let varname '=' Exp "in" Exp { Let $2 $4 $6 }
| if Exp then Exp else Exp { If $2 $4 $6 }
| "Lam" varname "->" Exp { Abs $2 $4 }
| Form { $1 }
Form
: Juxt { $1 }
Juxt
: Juxt Atom { App $1 $2 }
| Atom { $1 }
Atom
: '(' Exp ')' { $2 }
| number { Value $ Number $1 }
| varname %prec VAR { Var $1 }
| Binfs { Value $ Binf $1 }
Binfs
: "eq?" { BinfEqual }
| '/' { BinfDiv }
| '*' { BinfTimes }
| '+' { BinfPlus }
| '-' { BinfMinus }
| '>' { BinfGT }
| '<' { BinfLT }