【问题标题】:bison how to get the token value (not semantic value)野牛如何获取令牌值(不是语义值)
【发布时间】:2014-10-29 23:58:57
【问题描述】:

是否可以恢复代币的价值?

我有一个类似的规则:

unaryOperation:
      NOT       { $$ = new UnaryOP(NOT); }
    | PLUS      { $$ = new UnaryOP(PLUS); }
    | MINUS     { $$ = new UnaryOP(MINUS); }
    ;

NOT、PLUS 和 MINUS 是标记,我也在我的程序中使用生成的定义。是否有可能恢复这些数据而不是在同一行重复自己?

我对语义值不感兴趣,所以我这样写是不正确的:

unaryOperation:
      NOT       { $$ = new UnaryOP($1); }
    | PLUS      { $$ = new UnaryOP($1); }
    | MINUS     { $$ = new UnaryOP($1); }
    ;

谢谢

【问题讨论】:

  • @rici 建议使用语义值来恢复元素的数据。但是,我试图不使用这个值。我解决了扩展 UnaryOP 的问题:UnaryNot、UnaryPlus 和 UnaryMinus。我认为这不是一个好的解决方案...

标签: bison flex-lexer bisonc++


【解决方案1】:

bison 不需要知道哪个令牌被识别,因为该信息实际上是堆栈状态的一部分。但是,如果启用了调试,野牛表会包含每个归约右侧的编码版本,这允许内置跟踪功能生成人类可读的跟踪。

理论上你也可以使用这些信息,但这不是你想要的,因为 bison 将 flex 令牌编号转换为连续序列(以允许更紧凑的解析表)并且不提供任何翻译方式他们回来了。所以会很乏味。

更好的解决方案是使用您当前忽略的语义值(假设它具有整数变体)。分配语义值的成本是微不足道的,因为野牛确实需要将每个标记的语义值初始化为某种东西。

因此,一个合理的 flex/bison 解决方案可能是:

弹性

%union {
   int intval;
   /* ... other semantic values */
}

%%

 /* All the other rules come first */

 /* Default rule which just passes any character through to bison
  * (see note)
  */
.  { return (yylval.intval = yytext[0]); }

野牛

 /* This declaration is only necessary because these tokens
  * have a semantic value
  */
%token <intval> '-' '+' '!'

%%

unaryOperation
    : '!'     { $$ = new UnaryOP($1); }
    | '+'     { $$ = new UnaryOP($1); }
    | '-'     { $$ = new UnaryOP($1); }
    ;

注意:我删除了标记名称NOTPLUSMINUS,因为我更喜欢使用单字符标记来表示自己的风格。这里的区别在于 flex 规则 also 设置语义值(相同的数字)。如果运算符是多字符的,您也可以这样做:

弹性

'!='   { return (yylval.intval = NOTEQUAL); }

【讨论】:

  • 我在要求使用前瞻符号(正常和翻译)之前尝试过,但是我没有成功。 :( 另一件事,是否可以在 flex 文件上使用 %union?flex 手册说它是由野牛生成的......
  • @RicardoLucca:前瞻符号是yychar,但它对您没有任何帮助,因为它是下一个符号。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-14
  • 2016-07-07
  • 1970-01-01
相关资源
最近更新 更多