[英]Using Alex in Haskell to make a lexer that parses Dice Rolls
我正在使用 Alex + Happy 為 Haskell 中的 DSL 制作解析器。 我的 DSL 使用擲骰子作為可能表達式的一部分。
有時我有一個要解析的表達式,如下所示:
[some code...] 3D6 [... rest of the code]
這應該大致翻譯為:
TokenInt {... value = 3}, TokenD, TokenInt {... value = 6}
我的 DSL 也使用變量(基本上是字符串),所以我有一個特殊的標記來處理變量名。 所以,有了這個令牌:
"D" { \pos str -> TokenD pos }
$alpha [$alpha $digit \_ \']* { \pos str -> TokenName pos str}
$digit+ { \pos str -> TokenInt pos (read str) }
我現在使用解析時得到的結果是:
TokenInt {... value = 3}, TokenName { ... , name = "D6"}
這意味着我的詞法分析器“讀取”了一個Integer和一個名為“D6”的變量。
我嘗試了很多東西,例如,我將令牌D更改為:
$digit "D" $digit { \pos str -> TokenD pos }
但這只是消耗數字:(
PS:我使用 PosN 作為包裝器,不確定是否相關。
我想 go 的方式是將TokenD
類型擴展到TokenD Int Int
所以為了方便我會使用basic
包裝器
$digit+ D $digit+ { dice }
...
dice :: String -> Token
dice s = TokenD (read $ head ls) (read $ last ls)
where ls = split 'D' s
可以在這里找到split
。
這是一個額外的步驟,通常在句法分析期間完成,但在這里並沒有太大的傷害。
此外,我不能讓 Alex 解析$alpha
的TokenD
而不是TokenName
。 如果我們有Di
而不是D
那沒問題。 來自 Alex 的文檔:
當輸入 stream 匹配多個規則時,匹配輸入 stream 的最長前綴的規則獲勝。 如果仍有多個規則匹配相同數量的字符,則文件中最早出現的規則獲勝。
但是你的代碼應該可以工作。 我不知道這是否是 Alex 的問題。
我決定我可以使用以小寫字母開頭的變量(例如 Haskell 變量),因此我將詞法分析器更改為僅在變量以小寫字母開頭時才解析它們。 這也解決了一些其他保留字可能出現的問題。
我仍然很想知道是否有其他解決方案,但問題本身已經解決了。
謝謝你們!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.