我想用Token list -> Ast * Token list
類型構建活動模式。在遞歸下降解析器中縮短活動模式
我有一個簡單的帕斯卡語法<program> ::= "program" <id> ";" <block> "."
。通過重構代碼,這個語法,我必須做出Program
,Identifier
和Block
模式,如:
let rec (|Program|_|) tokens =
match tokens with
| Token.Program :: tokens ->
match tokens with
| Identifier (identifier, tokens) ->
match tokens with
| Semicolon :: tokens ->
match tokens with
| Block (block, tokens) ->
match tokens with
| Dot :: tokens -> Some (Ast.Program (identifier, block), tokens)
| _ -> failwithf "Expected %A" Dot
| _ -> failwith "Expected Block"
| _ -> failwithf "Expected %A" Semicolon
| _ -> failwith "Expected Identifier"
| _ -> failwithf "Expected %A" Token.Program
and (|Identifier|_|) tokens =
match tokens with
| Token.Identifier identifier :: tokens ->
Some (Ast.Identifier identifier, tokens)
| _ -> failwith "Expected Identifier"
...
因爲有很多重複的選項None
,我試圖縮短模式是:
type rec (|Program|_|) tokens =
match tokens with
| Token.Program :: Identifier (ident, Semicolon :: Block (block, Dot :: rest)) ->
Some (Ast.Program (identifier, block), rest)
| _ -> None
新模式能否按預期工作?我怎樣才能使活動模式更短,但不知怎的,也會返回錯誤輸入的錯誤?
另外,我讀到FParsec使用monad來分析和保留錯誤,我怎樣才能做出類似FParsec的簡單計算表達式。
對於編寫計算表達式,https://fsharpforfunandprofit.com/series/computation-expressions.html是你最好的指導。 – rmunn
另外,您的AST設計對我來說看起來有點奇怪。爲什麼「標識符」和「塊」聯合案例吸收了「內部」中的以下標記,但「程序」標記沒有?我期望看到一些更類似於具有標識符ident :: tokens的匹配令牌,即只有「標識符」情況「吸收」了標識符的名稱。 「標識符」情況下的所有以下標記都沒有意義。我不知道我是否清楚地傳達了我想說的話;你明白我的意思嗎,還是應該嘗試重新翻譯它? – rmunn
@rmunn所有活動模式吸收令牌並返回剩餘的模式。因爲我從http://stackoverflow.com/a/4418823/7821462閱讀,他們應該有類型'令牌列表 - > Ast *令牌列表。 – MiP