gpt4 book ai didi

parsing - 与 Alex 和 Happy 一起管理职位信息

转载 作者:行者123 更新时间:2023-12-03 12:20:24 25 4
gpt4 key购买 nike

我正在学习使用 Alex 和 Happy 编写一个小型编译器。我想为我的 AST 节点维护行和列信息,以便向用户提供有意义的错误消息。为了说明我打算如何做,我写了一个小例子(见下面的代码),我想知道我解决问题的方式(将 AlexPosn 附加到 token ,将多态属性字段附加到 AST 节点, 使用 tkPos 和 astAttr) 是很好的风格,或者如果有更好的方法来处理位置信息。

词法分析器.x:

{
module Lexer where
}

%wrapper "posn"

$white = [\ \t\n]

tokens :-

$white+ ;
[xX] { \pos s -> MkToken pos X }
"+" { \pos s -> MkToken pos Plus }
"*" { \pos s -> MkToken pos Times }
"(" { \pos s -> MkToken pos LParen }
")" { \pos s -> MkToken pos RParen }

{
data Token = MkToken AlexPosn TokenClass
deriving (Show, Eq)

data TokenClass = X
| Plus
| Times
| LParen
| RParen
deriving (Show, Eq)

tkPos :: Token -> (Int, Int)
tkPos (MkToken (AlexPn _ line col) _) = (line, col)
}

解析器.y:
{
module Parser where

import Lexer
}

%name simple
%tokentype { Token }
%token
'(' { MkToken _ LParen }
')' { MkToken _ RParen }
'+' { MkToken _ Plus }
'*' { MkToken _ Times }
x { MkToken _ X }

%%

Expr : Term '+' Expr { NAdd $1 $3 (astAttr $1) }
| Term { $1 }

Term : Factor '*' Term { NMul $1 $3 (astAttr $1) }
| Factor { $1 }

Factor : x { NX (tkPos $1) }
| '(' Expr ')' { $2 }


{
data AST a = NX a
| NMul (AST a) (AST a) a
| NAdd (AST a) (AST a) a
deriving (Show, Eq)

astAttr :: AST a -> a
astAttr (NX a) = a
astAttr (NMul _ _ a) = a
astAttr (NAdd _ _ a) = a

happyError :: [Token] -> a
happyError _ = error "parse error"
}

主要.hs:
module Main where

import Lexer
import Parser

main :: IO ()
main = do
s <- getContents
let toks = alexScanTokens s
print $ simple toks

最佳答案

我个人对你描述的风格很满意。但是,它非常手动,我希望至少提供一种可能更易于管理的替代方案。

如果你往下看一点 documentation for alex wrappers ,您会注意到 monad 和 monadstate 包装器都包含位置信息。缺点是你现在将整个东西包裹在一个 monad 中,它会使解析器稍微复杂化。但是,通过将其包装在 monad 中,解析的结果是 Alex a这意味着您在创建 ast 节点时可以完全访问行和列信息。现在这只是从词法分析器中删除了一些样板,并没有做更多的事情。

通过这样做,您还可以使用 token 随身携带 AlexState,但这可能是不必要的。

如果您在实际修复解析器以处理 monad/monadstate 包装器时需要帮助,我写了一篇关于我如何设法让它在这里工作的回复:How to use an Alex monadic lexer with Happy?

关于parsing - 与 Alex 和 Happy 一起管理职位信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20590313/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com