3

課題で構成される非常に単純な言語のLALR文法を作成しようとしています。例えば:

foo = "bar"
bar = 42

言語は、値のリストも処理する必要があります。次に例を示します。

foo = 1, 2, 3

しかし、私は複数行のリストも処理したいと思います。

foo = 1, 2
      3, 4

末尾のコンマ(シングルトンと言語の柔軟性のため):

foo = 1,
foo = 1, 2,

そして明らかに、両方同時に:

foo = 1,
      2,
      3,

末尾のコンマまたは複数行のリストを使用して文法を書くことはできますが、両方を同時に書くことはできません。

私の文法は次のようになります。

content : content '\n'
        : content assignment
        | <empty>

assignment : NAME '=' value
           | NAME '=' list

value : TEXT
      | NUMBER

list : ???

注:この種のコードを禁止するには、文法に「\n」が必要です。

foo
=
"bar"

よろしくお願いします、

アントワーヌ。

4

2 に答える 2

2

構成言語は基本的に自由形式のようです。文法で改行をトークンにすることを忘れてしまいます。改行制限が必要な場合は、字句タイインルールとしてハックできます。これにより、パーサーはレクサーに追加された小さなAPIを呼び出して、文法のどこにあるかをレクサーに通知し、レクサーは受け入れるかどうかを決定できます。改行またはエラーでそれらを拒否します。

この文法を試してください。

%token NAME NUMBER TEXT

%%

config_file : assignments
            | /* empty */
            ;

assignments : assignment
            | assignments assignment
            ;

assignment : NAME '=' values comma_opt

comma_opt : ',' | /* empty */;

values : value
       | values ',' value
       ;

value : NUMBER | TEXT ;

それは私のために衝突することなく構築されます。私はそれを実行しませんでしたがy.output、トランジションが正気であるように見えるカジュアルな読書。

もちろん、この文法は次のことを可能にします

foo = 1, 2, 3, bar = 4, 5, 6 xyzzy = 7 answer = 42

レクサーとの追加の通信なし。

制限は、改行は値でのみ許可されることを意味します。2つのNAMEトークンが同じ行に表示されてはならず、=は前のNAMEと同じ行に表示されている必要があります(おそらく最初の値も表示されている必要があります)。

基本的に、パーサーが最初の値をスキャンすると、レクサーに「値は現在スキャンされています。改行の許可をオンにしてください」と伝えることができます。そして、comma_optが減少すると、これを再びオフにすることができます。がcomma_opt削減されると、レクサーはNAME次の割り当てのトークンを既に読み取っている可能性がありますが、これが前の行とは異なる行で発生していることを確認できNAMEます。とにかく、レクサーが正確な行数を追跡する必要があります。

于 2012-03-15T05:12:11.740 に答える
0

私はこれについてあまり経験がありませんが、これはうまくいくでしょうか?

listvalue : value ,
          | value '\n'
          | value , '\n'

list : listvalue list
于 2012-03-14T05:43:19.010 に答える