2

私は言語処理が初めてで、Irony を使用して次の構文のパーサーを作成したいと考えています。

name1:value1 name2:value2 name3:value ...

ここで、name1 は xml 要素の名前で、value は要素の値で、スペースを含めることもできます。

含まれているサンプルを次のように変更しようとしました。

    public TestGrammar()
    {
        var name = CreateTerm("name");
        var value = new IdentifierTerminal("value");

        var queries = new NonTerminal("queries");
        var query = new NonTerminal("query");
        queries.Rule = MakePlusRule(queries, null, query);
        query.Rule = name + ":" + value;
        Root = queries;
    }

    private IdentifierTerminal CreateTerm(string name)
    {
        IdentifierTerminal term = new IdentifierTerminal(name, "!@#$%^*_'.?-", "!@#$%^*_'.?0123456789");
        term.CharCategories.AddRange(new[]
                                         {
                                             UnicodeCategory.UppercaseLetter, //Ul
                                             UnicodeCategory.LowercaseLetter, //Ll
                                             UnicodeCategory.TitlecaseLetter, //Lt
                                             UnicodeCategory.ModifierLetter, //Lm
                                             UnicodeCategory.OtherLetter, //Lo
                                             UnicodeCategory.LetterNumber, //Nl
                                             UnicodeCategory.DecimalDigitNumber, //Nd
                                             UnicodeCategory.ConnectorPunctuation, //Pc
                                             UnicodeCategory.SpacingCombiningMark, //Mc
                                             UnicodeCategory.NonSpacingMark, //Mn
                                             UnicodeCategory.Format //Cf
                                         });
        //StartCharCategories are the same
        term.StartCharCategories.AddRange(term.CharCategories);
        return term;
    }

ただし、値にスペースが含まれている場合、これは機能しません。これは、構文を変更せずに (Irony を使用して) 実行できますか (値を引用符で囲むなど)?

どうもありがとう!

4

1 に答える 1

0

キーと値のペアの間に改行が含まれていれば、簡単に達成できます。私は「皮肉」についての知識はありませんが、私の最初の感覚は、素朴な文法の説明だけを考えると、これを処理するパーサー/レクサー ジェネレーターはほとんどないということです。これには、本質的に無制限の先読みが必要です。

概念的には (私はこの製品について何も知らないため)、次のようにします。

スペースとコロンに基づいてトークン化します (つまり、スペースまたはコロンではないすべての連続する文字列は、何らかの「識別子」トークンです)。

次に、すべての「文」がコロンからコロンまで記述されるようにする必要があります。

sentence = identifier_list
         | : identifier_list identifier : sentence

これだけでは十分ではありませんが、少なくともアイデアは得られると思います。明確に解析できるように、identifier_list を単一の識別子と区別するように細心の注意を払う必要があります。同様に、ツールで優先順位と結合性を定義できる場合、「:」を左に非常にきつくバインドすることで回避できる可能性があります。これにより、文法は次のようになります。

sentence = identifier : identifier_list

そして、その動作は(identifier :) identifier_list.

于 2010-08-26T14:53:51.893 に答える