簡體   English   中英

使用 Haskell 中的 Alex 來制作解析骰子卷的詞法分析器

[英]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 }

但這只是消耗數字:(

  • 我可以用數字解析骰子嗎?
  • 或者至少解析 TokenInt-TokenD-TokenInt?

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 解析$alphaTokenD而不是TokenName 如果我們有Di而不是D那沒問題。 來自 Alex 的文檔:

當輸入 stream 匹配多個規則時,匹配輸入 stream 的最長前綴的規則獲勝。 如果仍有多個規則匹配相同數量的字符,則文件中最早出現的規則獲勝。

但是你的代碼應該可以工作。 我不知道這是否是 Alex 的問題。

我決定我可以使用以小寫字母開頭的變量(例如 Haskell 變量),因此我將詞法分析器更改為僅在變量以小寫字母開頭時才解析它們。 這也解決了一些其他保留字可能出現的問題。

我仍然很想知道是否有其他解決方案,但問題本身已經解決了。

謝謝你們!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM