Frage

Ich schreibe eine Lexer in Haskell. Hier ist der Code:

lexer :: String -> [Token]
lexer s
    | s =~ whitespace :: Bool =
        let token = s =~ whitespace :: String in
            lex (drop (length token) s)
    | s =~ number :: Bool =
        let token = s =~ number :: String in
            Val (read token) : lex (drop (length token) s)
    | s =~ operator :: Bool =
        let token = s =~ operator :: String in
            Oper token : lex (drop (length token) s)
    | otherwise = error "unrecognized character"
    where
        whitespace = "^[ \t\n]"
        number = "^[0-9]*(\.[0-9]+)?"
        operator = "^[+-*/()]"

data Token = Val Int | Oper String

Es gibt zwei Probleme, die ich habe. Eine, die Zahl regex "^[0-9]*(\.[0-9]+)?" wirft diesen Fehler:

lexical error in string/character literal at character '['

Und wenn ich die Zeile mit kommentieren Sie sie aus und die Teil der Funktion, dass Anwendungen, ich diesen Fehler:

Couldn't match expected type `Token'
           against inferred type `(String, String)'
      Expected type: [Token]
      Inferred type: [(String, String)]
    In the expression: lex (drop (length token) s)
    In the expression:
        let token = s =~ whitespace :: String
        in lex (drop (length token) s)

Ich habe keine Ahnung, warum ich immer entweder dieser Fehler. Kann mir jemand helfen?

War es hilfreich?

Lösung

Backslash als Escape-Zeichen in Zeichenkette, wie in "\n" für eine Zeichenfolge, die eine neue Zeile verwendet. Wenn Sie ein Backslash wollen, müssen Sie es als "\\" zu entkommen. Das ist das Problem in der Regex "^[0-9]*(\.[0-9]+)?", die Haskell-Parser versuchen "\." als normalen Zeichenfolge Flucht- und würgt auf mich zu interpretieren ist (wahrscheinlich, weil es keine solche Flucht). Wenn Sie die Regex als "^[0-9]*(\\.[0-9]+)?" der Fehler weggeht schreiben.

Der Grund für die Art Problem ist, dass Sie rufen Sie lex aus dem Standard-Prelude in lex (drop (length token) s), welche Art String -> [(String, String)] hat. Wahrscheinlich wollten Sie einen rekursiven Aufruf an Ihre Funktion lexer stattdessen tun ...

Andere Tipps

Beachten Sie auch, dass "^[0-9]*(\\.[0-9]+)?" Spiele einen leeren String oder Zahlen wie 0,12 (statt 0,12), die Sie wahrscheinlich nicht wollen. Es ist ein ernstes Problem, weil es Ihre Funktion selbst verursachen würde unendlich nennen. Um dies zu beheben, ändern * bis +.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top