2014-10-27 2 views
0
data Expr = ExprNum Double -- constants 
      | ExprVar String -- variables 
      | ExprAdd Expr Expr 
      | ExprSub Expr Expr 
      | ExprNeg Expr -- The unary '-' operator 
      | ExprMul Expr Expr 
      | ExprDiv Expr Expr 
      deriving Show 

Это мой пользовательский тип данных. Я хочу обрабатывать арифметическое выражение, например (2+3 *4 - x), используя вышеуказанные типы данных без использования парсера buildExpression. Что я могу сделать?Как построить Parser в Haskell

Пожалуйста, помогите мне. Он должен обрабатывать приоритет оператора.

+0

Есть ли причина, по которой мы не можем использовать buildExpressionParser? Я предполагаю, что это означает, что вы используете parsec. Знаете ли вы, как левый фактор грамматики, чтобы он был действительно действительным? – alternative

+0

"' 'buildExpression' parser", вероятно, относится к [этому модулю Parsec] (https://hackage.haskell.org/package/parsec-3.1.9/docs/Text-Parsec-Expr.html). – duplode

ответ

3

Предположим, мы хотим построить парсер уровня addsub. Мы хотели бы сказать, что (без учета фактического возвращения правильных значений и просто сосредоточиться на сырой разборе)

addsub = muldiv >> oneOf "+-" >> muldiv 

Это действительно не работает. Но мы можем оставили фактор это, как

addsub = muldiv >> addsub' 
addsub' = many $ oneOf "+-" >> muldiv 

Где мы предполагаем muldiv является синтаксический анализатор для только умножения и деления, которые вы можете писать в подобной манере.

То есть, вместо того, чтобы использовать грамматику

addsub = addsub (+-) muldiv | muldiv 

Мы используем несколько более сложным, но на самом деле использовать на Parsec:

addsub = muldiv addsub' 
addsub' = (+-) muldiv addsub' | Nothing 

Что мы можем, конечно, реорганизовать последний в many который дает нам список выражений, которые мы добавим. Затем вы можете преобразовать его в любую форму, например, (Add a1 (Add a2 (Add a3))).

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