2009-10-20 3 views
0

Я пишу lexer в haskell. Вот код:Проблемы с Haskell lexer

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 

Есть две проблемы, которые возникают у меня. Во-первых, число регулярных выражений "^[0-9]*(\.[0-9]+)?" выдает эту ошибку:

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

И когда я закомментируйте строку, содержащую его и часть функции, которая использует его, я получаю эту ошибку:

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)

У меня есть не знаю, почему я получаю одну из этих ошибок. Кто-нибудь может мне помочь?

ответ

7

Обратные косые черты используются как escape-символы в строковых литералах, например, в "\n" для строки, содержащей новую строку. Если вам нужна буквальная обратная косая черта, вам нужно избежать ее как "\\". Это проблема в регулярном выражении "^[0-9]*(\.[0-9]+)?", анализатор Haskell пытается интерпретировать "\." как обычную строку escape и дросселирует на ней (вероятно, потому, что такого выхода нет). Если вы напишете регулярное выражение как "^[0-9]*(\\.[0-9]+)?", ошибка исчезнет.

Причина, по которой Вы звоните, lex со стандартной Прелюдии в lex (drop (length token) s), которая имеет тип String -> [(String, String)]. Вероятно, вы хотели сделать рекурсивный вызов своей собственной функции lexer ...

+0

Спасибо. : D В парсер! – Micah

2

Также обратите внимание, что "^[0-9]*(\\.[0-9]+)?" соответствует пустой строке или цифрам, например .12 (вместо 0.12), чего вы, вероятно, не хотите. Это серьезная проблема, потому что это заставит вашу функцию называть себя бесконечно. Чтобы исправить это, измените значение * на +.

 Смежные вопросы

  • Нет связанных вопросов^_^