如果我們把 Lexer.hs 中的 translateLoc 和 update 改成
import Debug.Trace (trace)
...
translateLoc (TsToken (L loc x) rest) = TsToken (L (update' loc x) x) (translateLoc rest)
where
update' NoLoc x = NoLoc
update' before@(Loc start (Pos path l c co)) x = result'
where result = Loc start (Pos path l (c + 1) (co + 1))
result' = trace ("translateLoc: " ++ show x ++ " before: " ++ show before ++ " after: " ++ show result) result
這樣如果我們的 source code 只有 "{True}" 按下 load 會在 run 起來的 vscode 的 output "GCL LSP Server" 視窗看到
translateLoc: { before: Loc (Pos "/workspaces/gcl-all/gcl-vscode/example/a.gcl" 1 1 0) (Pos "/workspaces/gcl-all/gcl-vscode/example/a.gcl" 1 1 0) after: Loc (Pos "/workspaces/gcl-all/gcl-vscode/example/a.gcl" 1 1 0) (Pos "/workspaces/gcl-all/gcl-vscode/example/a.gcl" 1 2 1)
translateLoc: True before: Loc (Pos "/workspaces/gcl-all/gcl-vscode/example/a.gcl" 1 2 1) (Pos "/workspaces/gcl-all/gcl-vscode/example/a.gcl" 1 5 4) after: Loc (Pos "/workspaces/gcl-all/gcl-vscode/example/a.gcl" 1 2 1) (Pos "/workspaces/gcl-all/gcl-vscode/example/a.gcl" 1 6 5)
translateLoc: } before: Loc (Pos "/workspaces/gcl-all/gcl-vscode/example/a.gcl" 1 6 5) (Pos "/workspaces/gcl-all/gcl-vscode/example/a.gcl" 1 6 5) after: Loc (Pos "/workspaces/gcl-all/gcl-vscode/example/a.gcl" 1 6 5) (Pos "/workspaces/gcl-all/gcl-vscode/example/a.gcl" 1 7 6)
整理一下就是
{
before 1 1 0, 1 1 0
after 1 1 0, 1 2 1
True
before 1 2 1, 1 5 4
after 1 2 1, 1 6 5
}
before 1 6 5, 1 6 5
after 1 6 5, 1 7 6
也就是 translateLoc 讀到 lexer 的輸入本來就是 1-based, 輸出也是沒變 但現在把結尾從 inclusive 往後改成 exclusive 了
而這段的註解我還沒完全弄懂:
-- According to the document in Data.Loc.Range, the original meaning of Loc is
-- different from how we use it as Range (to simply put, Range extends 1 in col and charOffset).
-- The lexer records tokens' ranges in Loc, and we use translateLoc to make it Range.
這段 code 是這時加的:
作者: geoffcysu
時間: 2022-09-01 17:48:44 +0800
Commit: 7cdc7e5d0546f4cccdf7e62be65db2b6830f55ba
Commit message: "Delete old Syntax.Parser, rename Syntax.Parser2 as the new Syntax.Parser."