トップ «前の日記(2017-01-29 (Sun)) 最新 次の日記(2017-02-19 (Sun))» 編集   RSS 1.0 FEED  

Journal InTime


2017-02-12 (Sun) [長年日記]

_ Textbringer 0.1.7

Textbringer 0.1.7をリリースした。変更点は、

  • EditorConfigのサポート。
  • CONFIG[:ambiguos_east_asian_width]を追加。 詳細はREADME参照。
  • Cモードの追加。
  • *Completions*バッファの追加。
  • 複数文字コマンドをエコーエリアに表示。

久々に以下のように長い正規表現を書いた。

TOKEN_REGEXP = /\G(?:
(?<preprocessing_directive>
  ^[ \t\f\v]*(?:\#|%:).*(?:\\\n.*)*[^\\]\n
) |
(?<comment>
  (?<multiline_comment> \/\* (?> (?:.|\n)*? \*\/ ) ) |
  (?<singleline_comment> \/\/ .*(?:\\\n.*)*(?<!\\)\n )
) |
(?<partial_comment>
  (?<multiline_comment> \/\* (?:.|\n)* ) |
  (?<singleline_comment> \/\/ .*? \\\n (?:.|\n)* )
) |
(?<keyword>
  (?:
    auto | break | case | char | const | continue | default | double | do |
    else | enum | extern | float | for | goto | if | inline | int | long |
    register | restrict | return | short | signed | sizeof | static | struct |
    switch | typedef | union | unsigned | void | volatile | while | _Bool |
    _Complex | _Imaginary
  ) \b
) |
(?<constant>
  (?<floating_constant>
    (?<decimal_floating_constant>
      (?<fractional_constant>
        (?<digit_sequence> [0-9]+ )? \. \g<digit_sequence> |
        \g<digit_sequence> \. )
          (?<exponent_part> [eE] [+\-]? \g<digit_sequence> )?
          (?<floating_suffix> [flFL] )?
    ) |
    (?<hexadecimal_floating_constant>
      (?<hexadecimal_prefix> 0x | 0X )
          (?<hexadecimal_fractional_constant>
            (?<hexadecimal_digit_sequence> [0-9a-fA-F]+ )? \.
                \g<hexadecimal_digit_sequence> |
            \g<hexadecimal_digit_sequence> \. )
          (?<binary_exponent_part> [pP] [+\-]? \g<digit_sequence> )
          \g<floating_suffix>? |
      \g<hexadecimal_prefix> \g<hexadecimal_digit_sequence>
          \g<binary_exponent_part> \g<floating_suffix>?
    )
  ) |
  (?<integer_constant>
    (?<decimal_constant> [1-9][0-9]* )
    (?<integer_suffix>
      (?<unsigned_suffix> [uU] ) (?<long_suffix> [lL] )?
      \g<unsigned_suffix> (?<long_long_suffix> ll | LL )?
      \g<long_suffix> \g<unsigned_suffix>?
      \g<long_long_suffix> \g<unsigned_suffix>?
    )? |
    (?<hexadecimal_constant>
      \g<hexadecimal_prefix> \g<hexadecimal_digit_sequence> )
          \g<integer_suffix>? |
    (?<octal_constant> 0 (?<octal_digit> [0-7] )* )
        \g<integer_suffix>?
  ) |
  (?<character_constant>
    ' (?<c_char_sequence>
        (?<c_char>
          [^'\\\r\n] |
          (?<escape_sequence>
            (?<simple_escape_sequence> \\ ['"?\\abfnrtv] ) |
            (?<octal_escape_sequence> \\ \g<octal_digit>{1,3} ) |
            (?<hexadecimal_escape_sequence>
              \\x \g<hexadecimal_digit_sequence> ) |
            (?<universal_character_name>
              \\u[0-9a-fA-F]{4} |
              \\U[0-9a-fA-F]{8} )
          )
        )+
      ) ' |
    L' \g<c_char_sequence> '
  )
) |
(?<string_literal>
  " (?<s_char_sequence>
      (?<s_char> [^"\\\r\n] | \g<escape_sequence> )+ ) " |
  L" \g<s_char_sequence>? "
) |
(?<identifier>
  (?<identifier_nondigit>
    [_a-zA-Z] |
    \g<universal_character_name> )
        (?: \g<identifier_nondigit> | [0-9] )*
) |
(?<punctuator>
  \[   |   \]   |   \(   |   \)   |   \{   |   \}   |
  \.\.\.   |   \.   |
  \+\+   |   \+=   |   \+   |
  ->   |   --   |   -=   |   -   |
  \*=   |   \*   |
  \/=   |   \/   |
  &&   |   &=   |   &   |
  \|\|   |   \|=   |   \|   |
  !=   |   !   |
  ~   |
  ==   |   =   |
  \^=   |   \^   |
  <:   |   <%   |   <<=   |   <<   |   <=   |   <   |
  >>=   |   >>   |   >=   |   >   |
  \?   |   ;   |
  :>   |   :   |
  ,   |
  \#\#   |   \#   |
  %>   |   %:%:   |   %:   |   %=   |   %
) |
(?<space>
  \s+
) |
(?<unknown>.)
    )/x

田中哲スペシャルのおかげでC99のBNFを書き写すだけだと思ったのも束の間、左再帰を避けたり、最左最長マッチに合わせて順番を入れ替えるのが結構大儀であった。

インデントの設定項目は(使ったことのない)xyzzyを参考に以下のようなものを用意した。

CONFIG[:c_indent_level] = 4
CONFIG[:c_indent_tabs_mode] = true
CONFIG[:c_continued_statement_offset] = 4
CONFIG[:c_case_label_offset] = -4
CONFIG[:c_label_offset] = -2

以下のように~/.textbringer.rbに設定するとRubyのソースとだいたい同じスタイルになるはず(バッファローカルの設定はindent_levelとindent_tabs_modeはc_が付かないので注意)。

add_hook :c_mode_hook, -> {
  buf = Buffer.current
  if buf.file_name &&
      File.dirname(buf.file_name).end_with?("/ruby")
    buf[:indent_level] = 4
    buf[:tab_width] = 8
    buf[:indent_tabs_mode] = true
    buf[:c_continued_statement_offset] = 4
    buf[:c_case_label_offset] = -2
    buf[:c_label_offset] = -2
  end
}

K&Rスタイルに対応してないのは仕様である。

_ ストームブリンガー

ストームブリンガー 永遠の戦士エルリック(マイクル ムアコック/井辻 朱美)

新訳版で読み進めていたがようやく第4巻の『ストームブリンガー』まで読了した。

第3巻所収の『薔薇の復讐』以外は旧訳で読んでいるはずだったが、記憶以上に呪われている感じだったので、Textbringerを使う時はバックアップに気を付けようと思う。

Tags: