gpt4 book ai didi

parsing - 如何有效利用Alex的起始码功能?

转载 作者:行者123 更新时间:2023-12-03 00:39:38 26 4
gpt4 key购买 nike

我开始学习Alex并相信我已经达到了有状态上下文会有所帮助的地步,但我不完全确定如何去做。我正在尝试对 erlang binaries 的有限子集进行 lex 分析。使用以下词法分析器:

{
module Main (main, Token(..), AlexPosn(..), alexScanTokens, token_posn) where
}

%wrapper "posn"

$digit = 0-9 -- digits
$alpha = [a-zA-Z] -- alphabetic characters
$dbl_quote = \"

tokens :-

$white+ ;
"," { tok (\p s -> Comma p) }
"<<" { tok (\p s -> BinaryOpen p) }
">>" { tok (\p s -> BinaryClose p) }
$dbl_quote [^$dbl_quote]* $dbl_quote { tok (\p s -> ErlStr p (init (tail s))) }
$digit+ { tok (\p s -> ErlInt p (read s)) }

{
-- action helpers:
tok :: (AlexPosn -> String -> Token) -> AlexPosn -> String -> Token
tok f p s = f p s

data Token =
Comma AlexPosn |
BinaryOpen AlexPosn |
BinaryClose AlexPosn |
ErlInt AlexPosn Integer |
ErlStr AlexPosn String
deriving (Eq, Show)

token_posn :: Token -> AlexPosn
token_posn (Comma p) = p
token_posn (BinaryOpen p) = p
token_posn (BinaryClose p) = p
token_posn (ErlInt p _) = p
token_posn (ErlStr p _) = p

main :: IO ()
main = do
s <- getContents
print (alexScanTokens s)
}

我做得很好。例如,

> alex so_erlang_lexer.x  && ghc --make -o erlexer so_erlang_lexer.hs && echo '<<"100", 1>>' | ./erlexer 
[1 of 1] Compiling Main ( so_erlang_lexer.hs, so_erlang_lexer.o )
Linking erlexer ...
[BinaryOpen (AlexPn 0 1 1),ErlStr (AlexPn 2 1 3) "100",Comma (AlexPn 7 1 8),ErlInt (AlexPn 9 1 10) 1,BinaryClose (AlexPn 10 1 11)]

我希望词法返回值等于Binary [ErlStr "100", ErlInt 1],但我还没有找到词法分析器它使用的起始代码在我脑海中响起。

  • GHC 的词法分析器 referenced here不使用任何 Alex 包装器。
  • Alex 自己关于 monad 和 monadUserState 包装器的文档 here让我不确定应该选择哪一个以及如何利用其中一个。
  • Alex 的 tiger 示例是最有希望的,但它太大了,我很难澄清我的无知。
  • 这个question使用 monad 解析器,但似乎没有使用它的状态功能。

有人愿意指导我吗?

最佳答案

我不太确定你想用词法分析器做什么,并且有足够的知识来指导你(但如果你需要的只是过滤无用的标记,亚历克斯的单子(monad)接口(interface)似乎有点矫枉过正),无论如何,这里有一个示例代码使用 AlexUserState 通过“monadUserState”包装器累积所选 token 。



{
module Main (main) where
}

%wrapper "monadUserState"

$digit = 0-9 -- digits
$alpha = [a-zA-Z] -- alphabetic characters
$dbl_quote = \"

tokens :-

$white+ ;
"," { ignoreToken }
">" { ignoreToken }
$dbl_quote [^$dbl_quote]* $dbl_quote { pushToken $ ErlStr . init . tail }
$digit+ { pushToken $ ErlInt . read }

{

alexEOF :: Alex ()
alexEOF = return ()

-- some useful interaces to the Alex monad (which is naturally an instance of state monad)
modifyUserState :: (AlexUserState -> AlexUserState) -> Alex ()
modifyUserState f = Alex (\s -> let st = alex_ust s in Right (s {alex_ust = f st},()))

getUserState :: Alex AlexUserState
getUserState = Alex (\s -> Right (s,alex_ust s))

-- Token definition minus position information for simplicity
data Token =
Comma |
BinaryOpen |
BinaryClose |
ErlInt Integer |
ErlStr String
deriving (Eq, Show)

newtype AlexUserState = Binary [Token]
deriving (Eq, Show)

alexInitUserState :: AlexUserState
alexInitUserState = Binary []


-- action helpers:
pushToken :: (String -> Token) -> AlexAction ()
pushToken tokenizer =
\(posn,prevChar,pending,s) len -> modifyUserState (push $ take len s) >> alexMonadScan
where
-- Here tokens are accumulated in reverse order for efficiency.
-- You need a more powerful data structure like Data.Sequence to preserve the order.
push :: String -> AlexUserState -> AlexUserState
push s (Binary ts) = Binary (tokenizer s : ts)

ignoreToken :: AlexAction ()
ignoreToken _ _ = alexMonadScan


runAlexScan :: String -> Either String AlexUserState
runAlexScan s = runAlex s $ alexMonadScan >> getUserState


main :: IO ()
main = getContents >>= print . runAlexScan

}

但我想主要问题是你似乎还没有足够熟悉 Haskell 中 monad 的概念和用法。 Alex 的单子(monad)接口(interface)实际上非常自然,并且是状态单子(monad)的典型,一旦您有了一些编码经验,您只需浏览生成的代码就可以轻松猜到。 (如果您猜错了,类型检查器很可能会发现相关错误。)

为此,由于这里似乎有很多关于 monad 的好问题和答案,我只是引用 Real World Haskell (其中关于分析的章节对我特别有帮助。)

但是,如果您碰巧已经对范畴论有所了解,那么学习单子(monad)的最快方法可能是直接深入研究一些相关论文(请记住,范畴论中的单子(monad)是 Action 的概括,就像在团体的行动中一样,它自然地适合编程环境。)为此,请参阅this list of papers about monads and arrows ,其中包括针对具有一定技术背景的人员的介绍性论文和教程。

顺便说一句,我刚刚开始学习 Erlang。您能指导一下吗?静态类型的缺乏没有让你感到困扰吗?您是否尝试过 cloud-haskell 并将其与 Erlang 进行比较?您认为在分布式编程环境中哪种语言最有生产力?

关于parsing - 如何有效利用Alex的起始码功能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12718051/

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