Skip to content

技術情報

marihachi edited this page Apr 18, 2021 · 6 revisions

Parser ルール

Parserと付いているルールは外部から呼び出し可能なパーサを表すルールです。

  • FullParser 全ての構文をサポート
  • PlainParser インライン構文のうち絵文字コード(Emoji shortcodes)とユニコード絵文字のみサポート
  • InlineParser インライン構文をサポート (内部パース向け)

Unicode絵文字のパース

PEGは基本的に事前に定義されたルールを使って文字列をパースするため、
jsの正規表現(RegExp)を使用したい場合は少しトリッキーな方法でパースすることになる。

1. パーサの現在位置から始まる絵文字を探す (matchUnicodeEmoji)

文字列の先頭にのみマッチするtwemojiの正規表現を入力データ(現在位置から最後までの文字列)に適用する。
マッチする場合、現在位置から絵文字シーケンスが始まることが分かる。
マッチした文字列の長さ(16bit符号単位の数)は手順2で使用するために保持しておく(setConsumeCount)。

2. 絵文字の長さだけパーサの現在位置を進める (consumeDynamically)

肯定先読み(関数)と繰り返しを使い、マッチした文字列の分だけ動的に入力データを消費する。
入力データを消費している間はカウンタ変数をデクリメントする。 カウンタの値が1以上(マッチした文字列の長さを超えていない)の間は肯定先読みでtrueを返し、そうでなければfalseを返して消費を中断する。

参考

https://misskey.io/notes/8jaxv3bqdj

Unicode絵文字→Twemojiとして表示する だからTwemojiで対応しているのを過不足なく指定する必要があってTwemojiと同じパターンを使ってるのだわ。他のパターンだとU+FE0Eが付く付かないのあたりがうまく合致しなかった気がするのだわ。

ハッシュタグの判定

「#」の前に改行またはスペースがある場合にハッシュタグとして認識する。

という仕様を満たそうとした場合、PEGには「後読み」が無いので直接この条件を書くことができない。 そのため、次のような条件で代用する:

textルールでスペースや改行以外の文字を消費する時、次の文字以降がhashtagとマッチする場合は次の文字の「#」まで消費する

これなら、先読みだけで実現できる。