CLIツール

  • 雨崎しのぶ
  • 2024-08-13

コマンドラインインターフェース

概要

正規表現のテストケースのいくつかの例はtest/ディレクトリに配置されており、fpm testコマンドで簡単に実行することができます。

これらに含まれるものの他に、正規表現のマッチングを確認したい場合には、バージョン3.2から導入されたコマンドライン・インターフェースのツールforgex-cliが利用可能です。 例えば、((a|b)*)*abababのマッチングをテストしたい場合には、次のコマンドを実行すると以下のような出力が得られます。

% forgex-cli find match lazy-dfa '((a|b)*)*' .match. 'ababab'
            pattern: ((a|b)*)*
               text: ababab
         parse time:        32.s
   compile nfa time:        49.s
dfa initialize time:        55.7μs
  dfa matching time:       643.s
    matching result:         T
 memory (estimated):      6781

========== Thompson NFA ===========
state    1: (?, 3)
state    2: <Accepted>
state    3: (?, 5)(?, 2)
state    4: (?, 3)
state    5: (["a"-"b"], 6)(?, 4)
state    6: (?, 5)
=============== DFA ===============
   1A: ["a"-"b"]=>2
   2A: ["a"-"b"]=>2
state    1A = ( 1 2 3 4 5 )
state    2A = ( 2 3 4 5 6 )
===================================

コマンドラインの出力は、上部の実行時間などを示す表と、下部のオートマトンの状態と遷移を表す行から構成されます。 このツールを使用して、正規表現マッチングのベンチマークや、デバッグおよびテストを行うことができます。

現在のところ、finddebugのコマンドが利用可能です。また、forgex-cilのコマンドはfpm runから実行することも可能です。

% fpm run forgex-cli --profile release -- find match forgex '((a|b)*)*' .match. 'ababab'
...
libforgex.a                            done.
forgex-cli.f90                         done.
forgex-cli                             done.
[100%] Project compiled successfully.
pattern: ((a|b)*)*
   text: ababab
   time:       487.1us
 result:         T

forgex-cli debugコマンド

以下に、forgex-cli debugコマンドのヘルプメッセージを示します。

% forgex-cli debug --help
Prints the debug representation provided by Forgex.

USAGE:
   forgex-cli debug <command> ...

COMMANDS:
   ast           Print the debug representation of an AST.
   thompson      Print the debug representation of a Thompson NFA.

debugコマンドでは、与えられたパターンについて、抽象構文木(AST)または非決定性有限オートマトン (NFA)を出力します。

以下はastサブコマンドを使用して正規表現パターンから構築されたASTを出力する例です。

% forgex-cli debug ast "((a|b)*)*"
Project is up to date
        parse time:        29.5us 
memory (estimated):       829
(closure(closure(or "a" "b")))

一方、ASTから変換されたNFAの構造を知りたい場合には、次のようにthompsonサブコマンドを実行します。

% forgex-cli debug thompson "((a|b)*)*"
Project is up to date
        parse time:        26.5us 
  compile nfa time:        42.4us 
memory (estimated):      6271

========== Thompson NFA ===========
state    1: (?, 3)
state    2: <Accepted>
state    3: (?, 5)(?, 2)
state    4: (?, 3)
state    5: (["a"-"b"], 6)(?, 4)
state    6: (?, 5)

Note: all segments of NFA were disjoined with overlapping portions.
===================================

このコマンドラインの出力では、それぞれのNFA状態について、左辺に状態番号と右辺にNFA遷移がセットで記述されています。

  • (["a"-"b"], 6)`という遷移は「文字コード表でaからbの範囲の文字が入力された場合に第6状態へ遷移する」という意味になります。
  • (?, 3)のような、入力文字が?となっているものは、ε(イプシロン)遷移と呼ばれるもので、入力文字列を消費せずに遷移可能であることを示しています。この例では受理状態を除いてε遷移が各NFA状態に含まれています。

forgex-cli findコマンド

以下にfindコマンドとmatchサブコマンドのヘルプメッセージの出力を示します。

% forgex-cli find --help
Executes a search.

USAGE:
   forgex-cli find <command> ...

COMMANDS:
   match         Search for full matches.
% forgex-cli find match --help
Executes a search for full matches.

USAGE:
   forgex-cli find match <engine>

ENGINES:
   dense         Search with the fully-compiled DFA regex engine.
   lazy-dfa      Search with the lazy DFA regex engine.
   forgex        Search with the top-level API regex engine.

findコマンドではmatchサブコマンドを指定し、その後ろにマッチングに使用する正規表現エンジンを指定します。 エンジンは現在のところ、lazy-dfa, dense, forgexを選択することができます。  

  • denseエンジンは、完全にコンパイルされたDFAを使用してマッチングを行います。
  • lazy-dfaエンジンは、DFAをon-the-flyで構築してマッチングを行います。
  • forgexを指定すると、Forgexの上位APIを使用してマッチングを行います。これの内部実装はlazy-dfaですが、APIを使用した時間のみが計測されます。

denselazy-dfaforgexの3個いずれかからエンジンを決めたら、通常のFortranコードでForgexのAPIを使って書くのと同様に、.in.演算子または.match.演算子を使用してパターンと文字列を指定してマッチングを行います。 なお、演算子の右引数を省略した場合には、空文字とのマッチングを試みて結果を表示します。

% forgex-cli find match lazy-dfa "a*b" .match. "ab"
            pattern: a*b
               text: ab
         parse time:        24.6us
   compile nfa time:        39.5us
dfa initialize time:        47.2us
  dfa matching time:       170.5us
    matching result:         T
 memory (estimated):      5707

========== Thompson NFA ===========
state    1: (?, 4)
state    2: <Accepted>
state    3: (b, 2)
state    4: (a, 5)(?, 3)
state    5: (?, 4)
=============== DFA ===============
   1 : a=>2
   2 : b=>3
   3A:
state    1  = ( 1 3 4 )
state    2  = ( 3 4 5 )
state    3A = ( 2 )
===================================

DFAの出力には、上部と下部に分けられます。 上部では、DFA状態番号と、遅延評価により入力文字列から構成されたDFA遷移を記述しています。 下部では、各DFA状態を冪集合構成法で構成されたNFA状態番号のセットを示しています。 ここで、DFA状態番号の後ろにAと書かれている場合、そのDFA状態が受理状態であることを意味しています。

なお、このコマンドを実行する際には、いくつかのオプションフラグを指定することができます。

% forgex-cli find match lazy-dfa --help
Executes a search for matches using a lazy DFA regex engine.

USAGE:
   forgex-cli find match lazy-dfa <pattern> .match. <text>
   forgex-cli find match lazy-dfa <pattern> .in. <text>

OPTIONS:
   --verbose     Print more information.
   --no-table    Suppresses the output of the property information table.
   --table-only  Print the property information table only.