UP | HOME

NOTE: ADT 風格 AST 標記位置訊息技巧

1. 定義

data Term
  = TmPos Position Term
  | -- 剩餘的 term constructor

對應的 error report monad

report : String -> Either (String, Maybe Position) a
report s = Left (s, Nothing)

addPos : Position -> Either (String, Maybe Position) a -> Either (String, Maybe Position) a
addPos pos (Left (msg, Nothing)) = Left (msg, Just pos)
addPos _ ma = ma

2. 用途

這個方法真正的巧妙之處在於,任何時候要讓 report monad 擁有 position 資訊都可以,也不會被其他人覆蓋掉。

在解析文字建構 term 的時候,也可以在任何程式裡加上位置資訊又不需要去修改本來的定義。假設 Parser a 是解析文字之後得出 a 的解析器 monad 簽名;那麼下列定義就可以為任何 Parser a 重新建構一個具有 Position 版本的 a

withPos : (Position -> a -> a) -> Parser a -> Parser a
withPos f p = f <$> getPosition <*> p

用上面的 Term 定義舉例,就會像是

withPos TmPos parseXxx

只要上面 parseXxxParser Term 即可。

Date: 2022-12-06 Tue 00:00
Author: Lîm Tsú-thuàn