0

我有语法:

%token T_SHARE
%token T_COMMENT T_PUBLIC T_WRITEABLE T_PATH T_GUESTOK T_VALID_USERS
       T_WRITE_LIST T_CREATE_MODE T_DIRECTORY_MODE
%union
{
    int number;
    char *string;
}

%token <string> T_STRING
%token <number> T_NUMBER T_STATE

%%

parameters:
   |parameters parameter
       ;
parameter:
   section_share
       |comment
....
section_share:
       '[' T_SHARE ']' {section_print(T_SHARE);}
   ;
comment:
   T_COMMENT '=' T_STRING {print(2);parameter_print(T_COMMENT);}
       ;

函数打印是: void print(int arg) { printf("%d\n", arg); }

但它将 print 的参数“2”打印为其他值,如“8508438”,没有规则。为什么?

4

1 回答 1

0

很难理解您要问什么,但我认为您将令牌的数字代码与其语义值混淆了。print(2)特别是,与您的“评论”规则相关的操作中的调用没有什么特别之处。它按字面意思复制到生成的解析器中,因此,给定print()函数的定义,每次触发该规则时都应打印文字“2”。我认为这就是你所说的你观察到的。

相反,如果您想打印与规​​则中的符号关联的语义值,则语法的形式为 $n,其中美元符号后面的数字是规则中所需符号的编号,从 1 开始计数。因此,在“注释”规则中,与 T_STRING 符号关联的语义值可以引用为$3. 例如:

comment:
    T_COMMENT '=' T_STRING { printf("The string is %s\n", $3); }
;

原始标记的语义值必须由您的词法分析器设置为可用;非终结符的语义值必须由语法中的动作设置。另请注意,中间规则操作会包含在计数中。

尽管可以在操作中直接使用诸如 your 之类的标记符号T_COMMENT,但这样做通常没有用处。这些符号将由 C 预处理器解析为特定符号的数字特征。生成的令牌代码与解析的特定值无关。

于 2013-10-28T22:21:11.750 回答