私が設計していない単純な独自言語を解析する必要があるため、言語を変更することはできません。C# で結果が必要なので、使いやすく、パーサーを実行するために外部ライブラリを必要としない TinyPG を使用しています。TinyPG は単純な LL(1) パーサーを生成します。
私が現在抱えている問題は、言語がファイルをセクションに分割する方法に関連しています。さまざまな種類の変数、初期値の設定、方程式の定義などのセクションがあります。変数を宣言するセクションだけを気にするので、残りは無視したいと思います。他のセクションのすべてのルールを知っているわけではなく、それらを理解する必要はありません。それらはコメントとして扱われる場合があります。
コード例を次に示します。
PARAMETER
Density AS REAL
CrossSectionalArea AS REAL
SET # Parameter values
T101.FO := "SimpleEventFOI::dummy";
T101.CrossSectionalArea := 1 ; # m2
EQUATION
OutSingleInt = SingleInt;
OutArrayInt = ArrayInt;
PARAMETER セクションと SET セクションは気にしますが、EQUATION セクションは気にしません。ご覧のとおり、問題はこれらのセクションに END マーカーがないことです。したがって、別のキーワードを取得したときにセクションが終了するが、新しいキーワードが新しいセクションを開始する可能性があることを文法に伝える方法がわかりません。私の試みでは、新しいセクションの開始キーワードが消費されて、古いセクションが閉じられます。
ここにリストした以外にも多くのセクションがあり、重要なものもあれば、そうでないものもあります。ステートメントの最後にセミコロンがない「PARAMETER のように見える」と、セミコロンがある「EQUATION のように見える」の 2 つのタイプに分類されるようです。この言語では、大文字と小文字や空白は区別されません。セクションの順序は任意です。(例: SET、EQUATION、PARAMETER) コメント以外はすべて 1 行で記述できます。
現在、正規表現を使用して興味のあるセクションを見つけ、それらをパーサーに渡すだけでこれを回避していますが、すべての場合に機能する正規表現を思い付くのにも苦労していますが、コメント内のキーワードを誤って拾うことはありません。問題を解決するためにこの回避策を拡張することになるかもしれませんが、文法で直接問題を解決する方がよいでしょう。これは LL(1) 言語ではない可能性があります。