如何在Parsec中实现下标运算符?

时间:2013-06-25 01:06:23

标签: haskell parsec

我在Parsec写一个解析器。左递归产品,如E - > E + E不能在LL解析器中轻松编写,因此Parsec提供buildExpressionParser,它支持中缀,后缀和前缀运算符。但是下标运算符呢?

E-> E [E]是否已实施? 如果我可以使用结束括号而不使用第二个表达式,那么我可以使用buildExpressionParser的Infix表条目来模拟它。想法?

编辑:我知道有一种左递归消除算法很可能适用于我的语法。我正在寻找一些简单或抽象的东西(例如buildExpressionParser)。否则我只会用Happy。

2 个答案:

答案 0 :(得分:1)

在我们的项目中,我们手动消除了表达式中的左递归。这可以通过以下方式实现:

我们创建了一个通用的表达式,由术语解析器参数化:

expressionGen :: MParser (Expr LocInfo) -> MParser (Expr LocInfo)
expressionGen term = buildExpressionParser precedenceTable term <?> "expression"
  where precedenceTable = -- unary, binary expressions

我们有一个普通的术语解析器,以及一个没有递归规则的术语解析器。有了它,我们可以解析(多个)下标运算符:

term :: MParser (Expr LocInfo)
term = do indBase <- termNoArray
          indexes <- many $ (brackets expression >>= return)
          return -- semantics
        <?> "term"

termNoArray :: MParser (Expr LocInfo)
termNoArray = -- normal terms

最后,我们有一个最顶层的表达式解析器:expression = expressionGen term

答案 1 :(得分:0)

技巧是将后缀下标运算符视为一个整体,包括索引表达式。

megaparsec/parsec-combinators项:

pExpr = makeExprParser pTerm operatorTable

...

parseSubscr :: Operator Parser Expr
parseSubscr =
  Postfix $ do
    symbol space "["
    index <- pExpr
    symbol space "]"
    pure $ \parent ->
      Subscript parent index