2013-05-30 2 views
2

Я работаю над математическим выражением Happy и парсером переменных. Проблема в том, что я не знаю, как сохранить значение переменной и использовать ее позже. Есть идеи?Haskell - Happy, математические выражения и парсер переменных

Это, как я признаю, выражения и переменные назначение:

genExp : exp     { $1 } 
     | variable '=' exp   { //here I want to save the value of the variable; something like this: insert variables $1 $3, where 'variables' is a Data.Map } 

Выражение может содержать переменную. Например:

a = 2 + 1 
a + 2 (now the parser must print 5) 

Мне нужно, чтобы сохранить значение переменной «а», когда анализатор разбора строки «а = 2 + 1» и получить значение переменной «а», когда парсера анализирует строку 'a + 2'

+0

Erm, этот вопрос на самом деле не ясен. Не могли бы вы перефразировать его? Образец кода и фактическая проблема, которую вы пытаетесь решить, тоже будут хороши. Благодарю. –

+0

Я отредактировал мой вопрос. –

ответ

0

Что вы хотите сделать, это отслеживать значение переменных во время оценки , а не при разборе. Давайте предположим, что вы разбираете свои выражения в следующих типов:

data Expr = Literal Int | Variable Var | Assign Var Expr | Add Expr Expr | ... 
newtype Var = Var String deriving (Ord, Eq, Show) 

Тогда вы могли бы просто передать карту вокруг оценочной функции с текущим значением всех переменных:

import qualified Data.Map as M 
import Control.Monad.State 

data Expr = Literal Int | Variable Var | Assign Var Expr | Add Expr Expr 
newtype Var = Var String deriving (Ord, Eq, Show) 

-- Each Expr corresponds to a single line in your language, so 
-- a = 2+1 
-- a + 2 
-- corresponds to 
-- [Assign (Var "a") (Add (Literal 2) (Literal 1)), 
-- Add (Variable (Var "a")) (Literal 2)] 
eval :: [Expr] -> Int 
eval es = last $ evalState (mapM eval' es) M.empty -- M.empty :: M.Map Var Int 
    where 
    eval' (Literal n) = return n 
    eval' (Variable v) = do 
     vs <- get 
     case M.lookup v vs of 
     Just x -> return x 
     _  -> error $ "variable " ++ show v ++ " is undefined!" 
    eval' (Assign v ex) = do 
     x <- eval' ex 
     modify (M.insert v x) 
     return x 
    eval' (Add a b) = do 
     x <- eval' a 
     y <- eval' b 
     return (x+y) 

Конечно, нет ничего не позволяют вам оценивать выражения при их анализе, устраняя необходимость в абстрактном синтаксическом дереве, таком как это. Общая идея такая же; вам нужно будет поддерживать некоторое состояние с вами во время всего синтаксического анализа, который отслеживает текущее значение всех ваших переменных.

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