在 [Day-22] 中,我們討論了 CodeMirror 可以利用它來做 語法的 Highlight,但是 CodeMirror 並不支援 SCSS 語法的高亮。
這時我們就需要自定義一個語法的 Highlight,這時就需要用到 Lezer.js 了。
下面我們就來說說 Lezer.js,如何利用昨天說到的 Grammar 來定義語法。
# init package.json
npm init -y
# The lezer packages used in our script
npm i -s @lezer/generator
# Rollup
npm i -D rollup
先來定義簡單的 grammar,用於解析 (100-(2+4)) 或 (a+1) 這種算式。
@top Program { expression }
expression { Name | Number | BinaryExpression }
@skip { space | Comment }
BinaryExpression { "(" expression ("+" | "-") expression ")" }
@tokens {
space { @whitespace+ }
Comment { "//" ![\n]* }
Name { @asciiLetter+ }
Number { @digit+ }
}
lezer-generator src/lang.grammar -o dist/lang.js
import {parser} from '../dist/lang.js';
const tree = parser.parse('(a+1)');
// 利用 iterate 走訪 tree 的每個節點,並輸出節點對應資訊
tree.iterate({
enter(node) {
const originStr = str.substring(node.from, node.to);
console.log('type=',node.name,' \t (from,to) =',`(${node.from},${node.to})`,' \t對應字串 =',originStr);
},
});
/*
type= Program (from,to) = (0,5) 對應字串 = (a+1)
type= BinaryExpression (from,to) = (0,5) 對應字串 = (a+1)
type= Name (from,to) = (1,2) 對應字串 = a
type= Number (from,to) = (3,4) 對應字串 = 1
*/