Я завершил последний вопрос моего назначения, в котором спрашивалось следующее:
"Добавить локальную конструкцию определения " let v = e в f ", где v - переменная иe и f являются выражениями. Это означает, что v имеет значение e с in f, и это переопределяет любое значение v в среде (или включающее в себя значение let). Как и в предыдущем примере, вам нужноподумайте о синтаксисе для этого, который вы можете легко проанализировать с расширением существующего синтаксического анализатора "
Моя проблема заключается в том, что предопределенный описанный ниже тип expr, используемый синтаксическим анализатором и компилятором в данной кодовой базе, не распознается в моей реализацииоператора let, и я получаю следующую ошибку:
Ошибка: это выражение имеет тип expr, но ожидалось выражение типа char
Я добавил функциональность всинтаксический анализатор, который переводит оператор let в форме " ~ var1 = exp1> exp2 ", где вывод синтаксического анализатора имеет форму Bes " (v1, e1, е2)".Это все проверено и работает.Мои проблемы возникают, когда я добавил регистр в оператор соответствия компилятора, который распознает только что упомянутую 2-ю форму;после сопоставления моя «препроцессорная» функция также вызывается, как показано ниже.Это должно взять v1, e1 и e2, совпадающие в компиляторе и рекурсивно совпадающие на e2, заменяя любой экземпляр переменной v1 выражением e1 перед возвратом этой обновленной формы выражения e2 для дальнейшей компиляции.Вместо этого я получаю ошибку соответствия выше.
ОПРЕДЕЛЕНИЕ ВЫРАЖЕНИЯ
type expr =
Num of int
| Var of char
| Add of expr*expr
| Mul of expr*expr
| Con of expr*expr*expr
| Bes of expr*expr*expr
ОПРЕДЕЛЕНИЕ ИНСТРУКЦИИ
type instr =
| Push of int
| Fetch of char
| Add2
| Mul2
| Con2
ДРУГИЕ ВИДЫ
type program = instr list
type stack = int list
ФУНКЦИЯ МОЕГО ПРЕДПРОЦЕССОРА
let rec preprocessor eo2 eo1 vo1 : expr =
match eo2 with
| Num n -> eo2
| Var v -> if (v = vo1) then eo1 else eo2
| Add (e1, e2) -> Add ((preprocessor e1 eo1 vo1),(preprocessor e2 eo1 vo1))
| Mul (e1, e2) -> Mul ((preprocessor e1 eo1 vo1),(preprocessor e2 eo1 vo1))
| Con (e1,e2,e3) -> Con ((preprocessor e1 eo1 vo1), (preprocessor e2 eo1 vo1), (preprocessor e3 eo1 vo1))
(* | Bes (v1,e1,e2) -> (preprocessor e2 e1 v1) *)
ФУНКЦИЯ КОМПИЛЕРА
(*
compile : expr -> instr list
*)
let rec compile e =
match e with
| Num n -> [Push n]
| Var v -> [Fetch v]
| Add (e1,e2) -> compile e2 @ compile e1 @ [Add2]
| Mul (e1,e2) -> compile e2 @ compile e1 @ [Mul2]
| Con (e1,e2,e3) -> compile e3 @ compile e2 @ compile e1 @ [Con2]
| Bes (v1,e1,e2) -> compile (preprocessor e2 e1 v1) @ [] (*ERROR SOURCE LINE*)
Я ожидаю, что функция препроцессора изменит любые переменные в под-выражении e2 на выражение e1, которое затем можно будет продолжить в процессе компиляции.Вместо этого я получаю сообщение об ошибке, сообщающее, что вместо ожидаемого символа был указан expr.Я пробовал несколько вещей, таких как использование операторов let для назначения e2 e1 и v1 новым переменным, где я явно предоставлял им типы expr (e2: expr) и т. Д., И я также пытался явно вернуть expr из препроцессора, но я все еще застрял,Кодовая база казалась слишком большой, чтобы просто выкидывать сюда, так что, если мне следовало опубликовать функциональные парсеры, дайте мне знать.Спасибо за любую помощь