1

アセットxchange形式のパーサーを構築しています。また、bisonファイルに%token-tableディレクティブを含めていますが、フレックスコードからは、テーブルまたはそれに関連付けられている定数にアクセスできません。これは、このコードをコンパイルしようとするときです。

Frame|FrameTransformMatrix|Mesh|MeshNormals|MeshMaterialList|Material {
    printf("A keyword: %s\n", yytext);
    yylval.charptr_type = yytext;

    int i;
    for (i = 0; i < YYNTOKENS; i++)
    {
        if (yytname[i] != 0
            && yytname[i][0] == '"'
            && !strncmp(yytname[i] + 1, yytext, strlen(yytext))
            && yytname[i][strlen(yytext) + 1] == '"'
            && yytname[i][strlen(yytext) + 2] == 0)
            return i;
    }
}

gccは、YYNTOKENSとyytnameの両方が宣言されていないと言います。では、トークンテーブルは最終的に非推奨になり、ワイプされたのでしょうか、それともどうしたのでしょうか。

4

3 に答える 3

1
于 2012-10-14T04:17:46.117 に答える
1

「静的」問題をすばやく簡単に回避する方法があります。私は、C から 6502 へのコンパイラ用に、各非終端記号の文字列表現を含む人間が読める抽象構文ツリーを印刷しようとしていました。これが私がやったことです...

最後のセクションの .y ファイルで、token_table という非静的変数を作成します。

%%
#include <stdio.h>

extern char yytext[];
extern int column;
const char ** token_table;
...

ここで、yyparse を呼び出すメイン メソッドで、yytname を token_table に割り当てます。

int main(int argc, char ** argv) {
    FILE * myfile;
    yydebug = 1;
    token_table = yytname;
    ...

これで、次のように extern として宣言するだけで、任意のコンパイル ユニットで token_table にアクセスできます。

extern const char ** token_table;

/* Using it later in that same compilation unit */
printf("%s", token_table[DOWHILE - 258 + 3]); /* prints "DOWHILE" */

AST の各ノードに対して、y.tab.h にある yytokentype 値を割り当てる場合は、単純に 258 を減算して 3 を追加して、token_table (yytname) にインデックスを付けます。yytokentype が列挙を開始する場所である 258 b/c を減算する必要があり、3 b/c を追加する必要があります。テーブル。

たとえば、生成された bison ファイルには次のものがあります。

static const char *const yytname[] =
{
    "$end", "error", "$undefined", "DOWHILE", "UAND", "UMULT", "UPLUS",
    "UMINUS", "UBANG", "UTILDE", "ARR", "NOOP", "MEMBER", "POSTINC",
    ...

そして、defines ヘッダー ( --defines=y.tab.h オプションを指定して bison を実行):

/* Tokens.  */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
   /* Put the tokens into the symbol table, so that GDB and other debuggers
      know about them.  */
   enum yytokentype {
     DOWHILE = 258,
     UAND = 259,
     UMULT = 260,
     ...
于 2013-06-16T22:47:22.777 に答える
0

静的シンボルの問題を回避する最も簡単な方法#includeは、bison 入力ファイルの 3 番目のセクションでレクサーを直接使用することです。

/* token declarations and such */
%%
/* grammar rules */
%%

#include "lex.yy.c"

int main() {
  /* the main routine that calls yyparse */
}

次に、.tab.c ファイルをコンパイルするだけです。必要なのはそれだけです。

于 2013-06-17T04:02:36.760 に答える