Функция синтаксического анализа в haskell - PullRequest
11 голосов
/ 17 января 2011

Я новичок в Haskell и пытаюсь разобрать выражения.Я узнал о Parsec, и я также нашел несколько статей, но я не понимаю, что я должен делать.Моя проблема в том, что я хочу дать выражение типа «x ^ 2 + 2 * x + 3», и результат должен быть функцией, которая принимает аргумент x и возвращает значение.Мне очень жаль, если это простой вопрос, но мне действительно нужна помощь.Спасибо!Код, который я вставил, взят из статьи, которую вы можете найти по этой ссылке .

import Control.Monad(liftM)
import Text.ParserCombinators.Parsec 
import Text.ParserCombinators.Parsec.Expr  
import Text.ParserCombinators.Parsec.Token  
import Text.ParserCombinators.Parsec.Language  

data Expr = Num Int       | Var String    | Add Expr Expr
          | Sub Expr Expr | Mul Expr Expr | Div Expr Expr
          | Pow Expr Expr
          deriving Show

expr :: Parser Expr
expr = buildExpressionParser table factor
    <?> "expression"

table = [[op "^" Pow AssocRight],
         [op "*" Mul AssocLeft, op "/" Div AssocLeft],
         [op "+" Add AssocLeft, op "-" Sub AssocLeft]]
    where
        op s f assoc
            = Infix (do{ string s; return f}) assoc
factor = do{ char '('
        ; x <- expr
        ; char ')'
        ; return x}
    <|> number
    <|> variable
    <?> "simple expression"

number :: Parser Expr
number = do{ ds<- many1 digit
        ; return (Num (read ds))}
    <?> "number"

variable :: Parser Expr
variable = do{ ds<- many1 letter
        ; return (Var ds)}
    <?> "variable"

1 Ответ

13 голосов
/ 17 января 2011

Это просто парсер для выражений с переменными. На самом деле интерпретация выражения - это совершенно отдельный вопрос.

Вы должны создать функцию, которая принимает уже проанализированное выражение и значения для переменных и возвращает результат вычисления выражения. Псевдокод:

evaluate :: Expr -> Map String Int -> Int
evaluate (Num n) _ = n
evaluate (Var x) vars = {- Look up the value of x in vars -}
evaluate (Plus e f) vars = {- Evaluate e and f, and return their sum -}
...

Я намеренно пропустил некоторые детали; надеюсь, изучив недостающие части, вы узнаете больше о Haskell.

В качестве следующего шага вам, вероятно, следует взглянуть на монаду Reader для удобного способа передачи карты переменных vars и использования Maybe или Error для сигнализации об ошибках, например, ссылка на переменную, которая не связана в vars, или деление на ноль.

...