-1

我正在使用Parsec/Megaparsec 作为解析器来实现编译器。我找不到重载 operator 的方法+,我想将它用于整数加法和字符串连接。可能吗?

4

1 回答 1

1

首先编写编译器以使用不同的运算符进行字符串连接,例如@. 当您运行并经过良好测试后,请查看您的代码。您可能会发现发生了两种情况之一,具体取决于您正在解析的语言和您使用的编译器体系结构。

一种可能性是解析器的解析部分与解析器的解析+部分完全分开@(例如,它们位于两个不同的解析器函数中,一个用于解析数字表达式,另一个用于解析字符串表达式)。如果发生这种情况,恭喜,您只需替换"@""+",运行一些测试,就可以了。

第二种可能性是和在同一个地方解析并产生具有不同构造函数的 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)"

如果您的编译器看起来不像这些示例,您必须发布一些代码,以便我们知道它的样子

于 2019-07-04T19:19:32.893 回答