Как разбить математическое выражение на токены? (Строка -> [Строка]) - PullRequest
0 голосов
/ 04 января 2019

Я знаю, что мой вопрос звучит обобщенно, и я действительно не знал, как Google для такой вещи, поэтому я приведу примеры того, что я имею в виду:

ghci> splitTok "12 + 564 * (5 - 38) / 223"
["12", "+", "564", "*", "(", "5", "-", "38", ")", "/", "223"]
ghci> splitTok " 5+2-42  *    (46/5 )"
["5", "+", "2", "-", "42", "*", "(", "46", "/", "5", ")"]

Как можно реализовать что-то подобное? Или, может быть, в Prelude есть функция, которая делает подобные вещи?

Ответы [ 2 ]

0 голосов
/ 05 января 2019

Кажется, просто сгруппировать цифры и удалить пробел. Попробуйте

import Data.Char (isSpace, isDigit)
import Data.List (groupBy)

splitTok = groupBy (\x y->isDigit x && isDigit y) . filter (not . isSpace)
0 голосов
/ 05 января 2019

Хорошо, я придумал уродливый хак, который делает эту работу. (К сожалению, вносит ошибку)

import Data.Char (isSpace, isDigit)

strip :: String -> String
strip = filter (not . isSpace)

addSpacing :: String -> String
addSpacing [a] = [a]
addSpacing (x:y:cs)
    | isDigit x && isDigit y = x : addSpacing rest
    | otherwise = x : ' ' : addSpacing rest
  where rest = y : cs

splitTok :: String -> [String]
splitTok = words . addSpacing . strip

Не удалось создать правильную строку токенов в этом примере:

ghci> splitTok "125 +   12 62 - 12  *( 51/  3)        "
["125","+","1262","-","12","*","(","51","/","3",")"]

Для большинства выражений работает нормально, хотя:

ghci> splitTok "4123-36522+12"
["4123","-","36522","+","12"]
ghci> splitTok "124 *(12 -(4+5*(331/7)))"
["124","*","(","12","-","(","4","+","5","*","(","331","/","7",")",")",")"]
...