我正在使用Parsec/Megaparsec as parser实现编译器。我找不到重载运算符+
的方法,我想将其用于整数加法和字符串连接。有可能吗?
答案 0 :(得分:0)
首先,编写编译器以使用其他运算符进行字符串连接,例如@
。当它运行并经过良好的测试后,请看一下您的代码。您可能会发现发生了两件事之一,具体取决于您要解析的语言和所使用的编译器体系结构。
第一个可能性是解析器解析+
的部分与解析@
的解析器的部分完全分开(例如,它们分为两个部分)不同的解析器函数,一个用于解析数字表达式,另一个用于解析字符串表达式。祝贺您,如果发生这种情况,您只需将"@"
替换为"+"
,运行一些测试,就可以了。
第二次的可能性是,+
和@
在同一位置被解析并产生具有不同构造函数的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)"
如果您的编译器看起来不像这些示例,则您必须发布一些代码,以便我们确实看到它。