0

よし、これで取り引きだ。

私の言語では、いくつかのコマンドがあります。

XYZ 3 5
GGB 8 9
HDH 8783 33

そして、私の Lex ファイルで

XYZ { return XYZ; }
GGB { return GGB; }
HDH { return HDH; }
[0-9]+ { yylval.ival = atoi(yytext); return NUMBER; }
\n  { return EOL; }

私のyaccファイルで

start : commands
    ;

commands : command
         | command EOL commands
    ;

    command : xyz
            | ggb
            | hdh
    ;

    xyz : XYZ NUMBER NUMBER { /* Do something with the numbers */ }
       ;

    etc. etc. etc. etc.

私の質問は、どうすればテキスト全体を取得できますか

XYZ 3 5
GGB 8 9
HDH 8783 33

まだNUMBERを返している間にコマンドに入る?

また、私の Lex が STRING [0-9a-zA-Z]+ を返し、その長さを検証したい場合、次のようにする必要があります

rule: STRING STRING { if (strlen($1) < 5 ) /* Do some shit else error */ }

または、実際に長さに応じて異なるトークンを返すトークンが Lex に含まれていますか?

4

3 に答える 3

1

字句アナライザー ( yylex()) が文字列全体を何らかの変数に格納するように調整すると、コードでそれにアクセスできます。適切なパーサーとの通信は通常のメカニズムを介して行われますが、分析される前に入力行全体を格納する別の変数 (おそらくファイルの静的変数ですが、マルチスレッドに注意してください) を潜ませることができないと言うものは何もありません。

于 2009-08-06T11:24:19.920 に答える
1

私があなたの最初の質問を正しく理解していれば、次のようなセマンティック アクションを実行できます。

{ $$ = makeXYZ($2, $3); }

これにより、必要に応じてコマンドの値を構築できます。

2 番目の質問については、語彙分析と文法分析の間、および文法分析と意味分析の間の境界は厳密ではなく、十分に固定されていません。それらを移動することは、説明の容易さ、エラーメッセージの明確さ、エラーが発生した場合の堅牢性などの要素間のトレードオフです。文字列の長さの検証を考えると、エラーが発生する可能性が非常に高く、異なる長さの異なる端末を返すことによって処理される場合、エラー メッセージはおそらく明確ではありません。したがって、可能であれば (文法にもよりますが)、メッセージを簡単に調整できる意味分析フェーズで処理します。

于 2009-08-06T06:24:39.167 に答える
0

使用しているように、次のように、YACC ソースにwithフィールドyylval.ivalが既にあります。unionival

%union {
    int ival;
}

次に、次のようにトークン タイプを指定します。

%token <ival> NUMBER

したがって、次のように、ルールのようにivalNUMBER トークンのフィールドに簡単にアクセスできます。$1

xyz : XYZ NUMBER NUMBER { printf("XYZ %d %d", $2, $3); }

2番目の質問では、ユニオンを次のように定義します。

%union {
    char*   strval;
    int     ival;
}

LEXソースでトークンタイプを指定します

%token <strval> STRING;
%token <ival> NUMBER;

これで、次のようなことができます

foo : STRING NUMBER { printf("%s (len %d) %d", $1, strlen($1), $2); }
于 2009-08-06T06:27:51.250 に答える