エレファント・ビジュアライザー調査記録

ビジュアルプログラミングで数式の変形を表すことを考えていくブロクです。

モノイド的構文解析(9)

モノイド的構文解析言語 MonParser (C# 形式 バージョン 0.3)

MonParser バージョン 0.3

BNF 形式の演算子C# 形式に合わせて変更します。「^」は BNF 形式では「->」とします。演算子の優先順位は C# に合わせます。

  • 「str(文字列)」は構文木で使われない文字列を表します。文字列は正規表現を表します。(BNF 形式では r"文字列")
  • 「st(文字列)」は構文木で使われない文字列を表します。文字列は正規表現ではありません。(BNF 形式では "文字列")
  • 「opr(文字列)」は構文木で使う文字列を表します。文字列は正規表現を表します。(BNF 形式では r'文字列')
  • 「op(文字列)」は構文木で使う文字列を表します。文字列は正規表現ではありません。(BNF 形式では '文字列')
  • 「構文式 >> 演算子の構文式」は左結合二項演算子の演算が連続した式を表します。コンストラクターによって二項演算の構文木を構成します。コンストラクターがないときはリストを構成します。
  • 「構文式 << 演算子の構文式」は右結合二項演算子の演算が連続した式を表します。コンストラクターによって二項演算の構文木を構成します。コンストラクターがないときはリストを構成します。
  • 「構文式 > 演算子の構文式」は後置単項演算子の演算が連続した式を表します。コンストラクターによって単項演算の構文木を構成します。
  • 「構文式 < 演算子の構文式」は前置単項演算子の演算が連続した式を表します。コンストラクターによって単項演算の構文木を構成します。
  • 「構文式1 & 構文式2」は構文式1と構文式2が連続する構文を表します。
  • 「構文式1 | 構文式2」は構文式1と構文式2のどちらかが成立することを表します。
  • 「構文式 * n」(n は 0 以上の整数)は構文式が n 回以上繰り返される構文を表します。
  • 「構文式 * -n」(-n は 負の整数)は構文式が n 回以下繰り返される構文を表します。
  • 「構文式 ^ コンストラクター」は構文式で表された構文を表し、構文式から構文木を構成します。(BNF 形式では「構文式 -> コンストラクター」)
演算子の優先順位

以下の順序となります。

MonParser (BNF 形式)の構文解析
        par str(string s) => par.StringRegExp(s);
        par st(string s) => par.String(s);
        par opr(string s) => par.OperatorRegExp(s);
        par op(string s) => par.Operator(s);

        par identifier => str(@"[A-Za-z_][A-Za-z0-9_]*") ^ syn.Identifier;
        par constructor => str(@"[A-Za-z_][A-Za-z0-9_]*") ^ syn.Constructor;
        par number => str(@"[0-9]+") ^ syn.Number;

        par term =>
              st("(") & expression & st(")")
            | identifier
            | constructor;

        par integer =>
              number ^ syn.Integer
            | op("-") & number ^ syn.Integer;

        par repeat_expression =>
              term
            | term & op("*") & integer ^ syn.RepeatExpression;

        par binary_expression =>
            repeat_expression > (op(">>") | op("<<")) ^ syn.BinaryExpression;

        par op_expression =>
            binary_expression > (op(">") | op("<")) ^ syn.BinaryExpression;

        par conjunction => op_expression >> op("&") ^ syn.Conjunction;

        par construction =>
              conjunction
            | conjunction & op("->") & constructor ^ syn.Construction;

        par expression => construction >> op("|") ^ syn.Expression;

        par expression_statement => expression ^ syn.ExpressionStatement;

        par definition => st("def") & identifier & st("=") & expression ^ syn.Definition;

        par statement =>
              definition
            | expression_statement;

        par program => statement >> st(";") ^ syn.Program_;