ElixirのLeex/Yeccで特定のログファイルを解析しようとしています。数時間後、私は最も簡単なシナリオを手に入れました。しかし、私は次のステップに進んでいきたいと思いますが、どうやってそれを行うのか分かりません。Elixir/ErlangのYeccパーサーでマップする項目を追加する
まず、ここでのログ形式の例です:
[!] plugin error detected
| check the version of the plugin
私の簡単な試みは、最初の行のみとあったが、それらの複数のエントリ、など:
[!] plugin error detected
[!] plugin error 2 detected
[!] plugin error 3 detected
働いたことテキストとログラインタイプ(警告)を含むすばらしい地図を私にくれました:
iex(20)> LogParser.parse("[!] a big warning\n[!] another warning")
[%{text: "a big warning", type: :warning},
%{text: "another warning", type: :warning}]
これは完璧です。しかし、上記のように、ログ行は次の行に続き、パイプ文字は|
と表示されます。私のレクサーはパイプ文字を持っていて、パーサはそれを理解することができますが、私のマップのtext
値に次の行を追加します。今のところ、マップ内の文字列として追加されます。だから、代わりに:
[%{text: "a big warning ", type: :warning}, " continues on next line"]
私が必要:
[%{text: "a big warning continues on next line", type: :warning}]
私は、ネット上の例を見て、それらのほとんどは、このような終了タグや閉じ括弧など本当に明確な「終了」トークンを、持っています、そしてそれでも、最終的なASTが正しいようにプロパティを追加する方法は私には分かりません。完全のために
は、ここに私のレクサーです:
Definitions.
Char = [a-zA-Z0-9\.\s\,\[\]]
Word = [^\t\s\.#"=]+
Space = [\s\t]
New_Line = [\n]
%New_Line = \n|\r\n|\r
Type_Regular = \[\s\]\s
Type_Warning = \[!\]\s
Pipe = \|
Rules.
{Type_Regular} : {token, {type_regular, TokenLine}}.
{Type_Warning} : {token, {type_warning, TokenLine}}.
{Char} : {token, {char, TokenLine, TokenChars}}.
{Space} : skip_token.
{Pipe} : {token, {pipe, TokenLine}}.
{New_Line} : skip_token.
Erlang code.
そして、私のパーサー:
Nonterminals lines line line_content chars.
Terminals type_regular type_warning char pipe.
Rootsymbol lines.
lines -> line lines : ['$1'|['$2']].
lines -> line : '$1'.
line -> pipe line_content : '$2'.
line -> type_regular line_content : #{type => regular, text => '$2'}.
line -> type_warning line_content : #{type => warning, text => '$2'}.
line_content -> chars : '$1'.
line_content -> pipe chars : '$1'.
chars -> char chars : unicode:characters_to_binary([get_value('$1')] ++ '$2').
chars -> char : unicode:characters_to_binary([get_value('$1')]).
Erlang code.
get_value({_, _, Value}) -> Value.
あなたも、ここまでなった場合は、はすでにありがとうございました!もし誰かが助けてくれたら、もっと大きな感謝を!
を私は今、この権利をテストすることはできませんが、私はあなたを考えます'line - > pipe line_content: '$ 2'.'を削除し、' line_content'を複数の行にするべきです。 PEGのような記法では、 'line_content = chars(pipe chars)*'、つまりcharsの後に0以上の '(pipe chars)'が続きます。 – Dogbert
@Dogbert aha okありがとう、私は複数の行の解析で検索しようとしましたが、良い例を得ることができません。私はあなたの提案をさらに検索します、おかげですでに束! –
私はこの時点で詳細を見る時間はありませんが、数ヶ月前にSFのErlang/Elixir Confでleex/yecc(Erlangで)を使っている小さなプロジェクトで雷の話をしました。スライドへのリンクはここにあります。リンクの最後に参考文献のリンクがあります。例:https://github.com/derek121/mrwhite –