Начните с написания вашим компилятором использования другого оператора для конкатенации строк, например @
. Когда он будет запущен и хорошо протестирован, взгляните на свой код. Вы, вероятно, обнаружите, что произошло одно из двух, в зависимости от языка, который вы анализируете, и используемой вами архитектуры компилятора.
Возможность 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)"
Если ваш компилятор не похож на эти примеры, вам придется опубликовать некоторый код, чтобы мы знали, как он выглядит .