✅vscode-scbのsyntaxをちゃんと作り直す
tokenization1
いきなり詰まるんだけど……
scbの1ページ分ってどう分解すればええんや?
lineだけじゃないよな?codeblockあるからblock的なのもいるよね?
code:bnf
<content> ::= <line> |
とりあえずblockは無視してlineの集まりだと考えることにする
code:bnf
<content> ::= <lines>
<lines> ::= <line> "\n" <lines> | <line>
<line> ::= <indent> <line-body>
<indent> ::= "" | " " <indent>
<line-body> ::=
line bodyはどう書くのがええやろ?列挙するのが早いか?
code:bnf
<line-body> ::= <plain-line> | <quote-line>
あとlineの中にinline要素としてリンクとリテラルがあるよな
え、どう書くん?sta.icon
リンク部分をL、プレーン部分をPとすると、
L
P
LP
PL
LPP
LPL
……
と無限にバリエーションあるわけですけども
code:bnf
<plain-line> ::= <plain-part> | <link-part> | <literal-part> | <plain-part><link-part> | <plain-part><literal-part> | ……
え、エグない?
いや、リンク・リテラル・プレーンだから、たぶん8種類くらいでいけるよな(順列?組み合わせ?的に)
それでも8個って鬼じゃない?
いや、たぶんかんたんに書ける書き方あるでsta.icon*2
scrapbox-parserも普通にorで並べてる感じだったし
なんか普通にムズイんだけど……
train.icontsか
覚えてない。すぐには読めない。
あとここでもmapとかfilterとかそういう奴がでてくる。これも覚えてない。
中々覚えられないんだよなー、これsta.icon*2
https://gyazo.com/dab8989f1d1953c8ebc2c0b5d887d8db
blockの塊として扱っている感じ?
blockには4種類あって、title, codeblock, table, line
ああ、なるほど、codeblockとtableは「n行からなる塊」かsta.icon*2
lineは「1行からなる塊」
titleは「先頭にある」「1行からなる塊」
lineの中は?
ひえー、いっぱいあるねsta.icon
Nodeつくってるってのはわかる
なんだっけ、なんか木構造?にして探索するみたいなのあったよな
アルゴリズムの世界
全然覚えてねえわ
が、ここではBNF定義ゲーであって、parser実装ではないので厳しいsta.icon
tokenization2
1 歯磨いてたひらめいたのでBNF少し試す
3 ダメそうなら、BNFで書き切るのを愚直に頑張るしかない
--- 1
code:bnf
<content> ::= <lines>
<lines> ::= <line> "\n" <lines> | <line>
<line> ::= <indent> <line-body>
<indent> ::= "" | " " <indent>
<line-body> ::= <plain-parts> | <quote-parts>
<quote-parts> ::= ">" <parts>
<plain-parts> ::= <parts>
<parts> ::= <part><parts> | <part>
<part> ::= <link-internal> | <link-external> | <literal> | <plain> | ""
で、あとは正規表現やろ
引用については、表現力が違う場合は <parts> とは別のをこしらえることになる
が、同じでええやろ。引用の中でもリンクやリテラルはハイライトしたいし
いけるやんsta.icon
ちょっと寝かせて問題なければ、これをsyntaxに落としますん
あー、codeblock入れてない。どうしよか
あとtextmateが行単位でしか扱えないって話も反映させる必要がある
たぶん<line> "\n" <lines>を<line> <lines>にすればいいと思ってるsta.icon
code:bnf
// L1
<content> ::= <lines>
<lines> ::= <line> <lines> | <block> <lines> | ""
// L2
<line> ::= <indent> <line-body>
<indent> ::= "" | " " <indent>
<block> ::= <codeblock>
// L3
<line-body> ::= <plain-parts> | <quote-parts>
<codeblock> ::= <codeblock-start> <codeblock-body> <codeblock-end>
<codeblock-start> ::= <indent> "code:" ".+"
<codeblock-body> ::= ".*"
<codeblock-end> ::= <indent> ":c"
// L4
<quote-parts> ::= ">" <parts>
<plain-parts> ::= <parts>
<parts> ::= <part><parts> | <part>
<part> ::= <link-internal> | <link-external> | <literal> | <plain> | ""
で、あとは正規表現やろ
早速詰まる
<lines> ::= <line> <lines> | <block> <lines> | ""
これどう書けばいいんだろ?
<line> <lines>
もっというとこれ
理解sta.icon
https://gyazo.com/965bf914dcd7ff4f074d24d8c2cb26e5
なので、
code:json
"content": {
"patterns": [{
"include": "#lines"
}]
},
"lines": {
"patterns": [
{ "include": "#line" },
{ "include": "#block" }
]
},
<line> ::= <indent> <line-body> これは?
patternsに列挙するだけ、は違うよな
これみたいに正規表現でキャプチャ分けるしかない?よな?
https://gyazo.com/4f818f1c17d59783fd714f0a0c4a5099
いや、ダメだ、これはtokenではなくnameの指定だからちゃう
かといって include で token 指定もできないっぽいし
https://gyazo.com/f34cd0a4f209caf134cb5e4810b78d09
列挙するしかないか?sta.icon*2
で、誤った順番(<indent> <line-body> <indent>みたいな)にならないよう、下位の正規表現をちゃんと書く
+1sta.icon
<indent> ::= "" | " " <indent>
ダメやろこれsta.icon*4
indent1, indent2, ...と全部別物にして、色も付けたいわけだからね
<indent> ::= <indent1> | <indent2> | <indent3> | ...
泥臭いけどこうするしかない
引用がわからん
>あああ
こういうパターンってどう書けばいいんや?
match & capture だと token 指定できないから無理だし
begin endだとendがわからん
$とかでええんかな?
---
書き直してみたんだが、これが出る
https://gyazo.com/0ba3126d0092ed7ac181fe7e90f1f8bf
https://gyazo.com/1041439491fe35ad1df75234700aa513
package.jsonとtmlanguageのパラメータ数が多すぎて意味わからん
こことここが同じ値じゃないとダメ、みたいな制約が多すぎるsta.icon*3
無闇にいじれない……
で、通りましたが
https://gyazo.com/6507b4e7246a2e9322cf71aefee8173d
全然ダメ~
1: indent1が優先される問題
2: 途中でquoteが発動している問題
1: indent1が優先される問題
わかったかもsta.icon*3
patternsの順番だ
先に書いた方が先に適用されていく
https://gyazo.com/e2c7ba202086995e3a82e1d082255cbe
2: 途中でquoteが発動している問題
今はこれで途中発動しちゃってる
code:json
"quote-parts": {
"begin": ">",
"end": "$",
https://gyazo.com/9aa6bc0cefe6cceae147939c457c6914
>ああああ>いいいい
最初のインデント部分はトークナイズしてて無いので
>ああああ>いいいい
で、>を指定しているから、まあどっちにもヒットするか
最初の>だけヒットさせるにはどうすればいい?sta.icon
こう?
code:json
"quote-parts": {
"begin": "^()*>",
"end": "$",
するとindent0しか発動しなくなる
https://gyazo.com/f582d4dc2c2701e15a881f57e0e72ea2
既にindent部分を分けてトークナイズしているので、まあそうかsta.icon
^>?
code:json
"quote-parts": {
"begin": "^>",
"end": "$",
ダメ。indent0しか発動しない
先読み後読み使うしかないよなぁこれ
できた?sta.icon*2
code:json
"quote-parts": {
"begin": "(?<=^( )*)>",
"end": "$",
https://gyazo.com/1e6664f9b7f7de45ea672ad758a153c1
やったー、ようやく通ったわぁ
嬉しいsta.icon*3
続いてコードブロック
<codeblock> ::= <codeblock-start> <codeblock-body> <codeblock-end>
ムズイ……
begincaptureは使えないか
いや、囲むだけだったわ
code:json
"codeblock": {
"begin": "(?<=^( )*)code\\:",
"end": "\\:c",
"name": "block.code.scb"
},
https://gyazo.com/6f0fb3db7de83a69d97e4be21b6e8a23