iT邦幫忙

2025 iThome 鐵人賽

DAY 25
0

考慮以下的需求:你有一個中文寫的純文字檔,裡頭是一篇中文的文章。基於某種理由,需要將文章裡的『如果』取代英文的 if 。很多人可能覺得,這還不簡單,字串取代就可以了。

然而,一旦當那篇中文的文章裡有一句亂來的句子:

牛奶不如果汁好喝。

前述 Naive 字串取代就會出錯。

要怎麼開發程式,才能避免程式受到上述這種亂來的句子的影響呢?

  • 先用形式語言學,將純文字檔裡的資料先做自然語言的語法樹解析,比方說:
;; 如果下雨,我就不去了。

S(句子)
├── CP(條件從句)
│   ├── C(連詞):如果
│   └── S(句子)
│       └── VP(動詞短語)
│           └── V(動詞):下雨
└── S(主句)
    ├── NP(名詞短語):我
    ├── Adv(副詞):就
    ├── Neg(否定詞):不
    ├── VP(動詞短語)
    │   └── V(動詞):去
    └── Part(語氣助詞):了
  • 對這些生成的語法樹做查詢 (query) ,先找出所有的連接詞 (C),再從連接詞裡去比對『如果』,這樣子就不會受到亂來句子的影響。

程式語言也一樣可以做語法樹解析。而實際上,現代的編輯器的進階功能:語法高亮度自動格式化、以及跳轉定義。這些能力背後的基石,也都是程式語言的語法樹解析。

問題概述

在 day24 我們提到了要使用 Tree-sitter 來解析程式碼,這就衍生了兩個主要的挑戰:

  1. Tree-sitter 如何生成 Fennel 的語法樹?
  2. 得到語法樹之後,如何查詢?

解題架構

第一個生成語法樹問題,其實是最難的,因為我們必須提供 Tree-sitter 一個 grammar.js ,裡頭要寫好 Fennel 語言的文法規則 (Grammar Rules) 。然而,幸運的是,Tree-sitter 官網上,許多冷門程式語言的文法規則早就存在了!

於是,可以得到下圖,下圖的左側就是 Tree-sitter 的輸出。
https://ithelp.ithome.com.tw/upload/images/20250925/20161869Ps78XzDoYb.jpg

查詢的問題,則可以善用 Neovim 的兩個 Ex 指令:

  • InspectTree
  • EditQuery

在 EditQuery 的視窗裡,輸入 Tree-sitter 查詢之後,比對成功的原始碼與語法樹區段就會自動反白,幫助你用肉眼確認,是否你的意圖與查詢的結果一致。Tree-sitter 的查詢語法,我到今天為止也沒有學會,我直接叫 LLM 幫我生成而已。

https://ithelp.ithome.com.tw/upload/images/20250925/20161869huFCHTZDF4.png

小結

自然語言和程式碼本身就是帶有隱性結構的資料,透過基於語法解析產生的語法樹,我們就能像應用資料庫一樣,以精準的方式來理解、查詢、操作其資料。


上一篇
專案研討—Fennel 的跳轉定義
下一篇
模式與原理—瓶頸與改進
系列文
在 Neovim 中探索 Fennel 與函數式編程26
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言