1

グローバル変数と C のバリエーションのいくつかのメソッド宣言を処理する文法があるとします。

program: (declaration)* (procedure)*;
declaration: typespec identifier ';';
procedure: typespec identifier '(' ')' ';';
typespec: 'char' | 'int';
identifier: ('a' .. 'z' | 'A' .. 'Z') ('A' - 'Z' | 'a' .. 'z' | '0' .. '9' | '_')*;

次のようなものを与えると:

int MAX;
char proc();

文法は int MAX を読み取ります。正しく、しかし、宣言ルールを2行目にも適用したいのですが、(に達すると失敗します。この時点で、バックトラックして次のルールである手続き用のルールを適用することを期待しています。誰か教えてください。なぜこれが起こっていないのですか?

4

1 に答える 1

1

すべての文法を投稿しましたか?あなたが投稿したようにコンパイルすることができませんでした...しかし、私はあなたが投稿したものを試して、あなたの例と一致させました:

program: (declaration)* (procedure)*;
statement: TYPE_SPEC IDENT ;
declaration: statement ';';
procedure: statement '(' ')' ';';

TYPE_SPEC 
    :   'char' | 'int';

IDENT 
    :   ('a' .. 'z' | 'A' .. 'Z') ('A' .. 'Z' | 'a' .. 'z' | '0' .. '9' | '_')*;

WHITESPACE
    :   ('\r' | '\n' | '\r\n' | ' ' | '\t' ) {$channel=HIDDEN;} 
    ;

トークンマッチングのレクサールール(大文字のルール)をパーサールールの一部にするのではなく、作成することをお勧めします。ご覧のとおり、それらのいくつかはすでに実行しています。

于 2012-02-15T00:37:30.363 に答える