Как перегрузить оператор в парсек / мегапарсек? - PullRequest
0 голосов
/ 04 июля 2019

Я реализую компилятор, используя Parsec / Megaparsec в качестве парсера .Я не могу найти способ перегрузки оператора +, который я хочу использовать как для сложения целых чисел, так и для конкатенации строк.Возможно ли это?

1 Ответ

0 голосов
/ 04 июля 2019

Начните с написания вашим компилятором использования другого оператора для конкатенации строк, например @. Когда он будет запущен и хорошо протестирован, взгляните на свой код. Вы, вероятно, обнаружите, что произошло одно из двух, в зависимости от языка, который вы анализируете, и используемой вами архитектуры компилятора.

Возможность first состоит в том, что часть вашего синтаксического анализатора, которая анализирует +, полностью отделена от части синтаксического анализатора, которая анализирует @ (например, они находятся в двух разных функциях синтаксического анализатора, одна для разбора числовых выражений и отдельного для разбора строковых выражений). Если это произошло, примите наши поздравления, вам просто нужно заменить "@" на "+", выполнить несколько тестов, и вы должны быть в порядке.

Возможность second заключается в том, что + и @ анализируются в одном и том же месте и создают узлы AST с разными конструкторами:

data Expr ... =
  ...
  | Plus Expr Expr     -- the '+' operator
  | Concat Expr Expr   -- the '@' operator
  ...

В этом случае у вас, вероятно, также есть какая-то часть вашего компилятора, которая генерирует код (и, надеюсь, некоторую информацию о типах):

codeGen (Plus e1 e2)
  = do (code1, typ1) <- codeGen e1
       (code2, typ2) <- codeGen e2
       if (typ1 == Num && typ2 == Num)
         then genPlus code1 code2
         else typeError "'+' needs numbers"
codeGen (Concat e1 e2)
  = do (code1, typ1) <- codeGen e1
       (code2, typ2) <- codeGen e2
       if (typ1 == Str && typ2 == Str)
         then genConcat code1 code2
         else typeError "'@' needs strings"

В этом случае вы должны изменить синтаксический анализатор / AST, чтобы свернуть AST только с одним общим конструктором:

data Expr ... =
  ...
  | ConcatPlus Expr Expr     -- the '+' operator for numbers and strings
  ...

и обрабатывать оба случая в генераторе кода, в зависимости от доступной информации о типе:

codeGen (ConcatPlus e1 e2)
  = do (code1, typ1) <- codeGen e1
       (code2, typ2) <- codeGen e2
       case (typ1, typ2) of
           (Num, Num) -> genPlus code1 code2
           (Str, Str) -> genConcat code1 code2
           _ -> typeError "'+' arguments must have same type (numbers or strings)"

Если ваш компилятор не похож на эти примеры, вам придется опубликовать некоторый код, чтобы мы знали, как он выглядит .

...