1

我必须使用 YACC 实现一个用于字符串操作的计算机。我必须实现像 +(用于连接字符串)或 *(用自身 n 次 strcat 一个字符串)之类的操作。这些操作返回一个字符串,我在非终端 t1 中使用它们.BUt 我也有返回数字的操作。这些操作在 t2 非终结符中。

例如我有:

      expr1: expr1 '+' expr1 { strcpy($$,$1); strcat($$,$3);}
       | expr1 '-' expr1 { strcpy($$,minus($1,$3));}    
           | | expr1 '*' NUMBER {strcpy($$,mul($1,$3));}
           |STRING;

我有:

     expr2 : STRING '?' STRING {strcpy($$nr_of_aparitions($1,$3));}
 ;

问题是 expr2 中定义的操作将始终返回一个 NUMBER。一切正常,直到:

如果我有'dfdf'?例如,“edfd”一切正常。当我必须在 expr2 中实现 expr1 时,问题就来了: expr1 ? expr2 因为会出现循环。你能建议什么吗?

4

1 回答 1

1

一般来说,您不需要关心所谓的“循环”和我所说的“递归”,即在 expr1 中使用数值表达式,反之亦然。

我将重写您的语法片段如下,以使您的代码更易于理解:

stringExpr : stringExpr '+' stringExpr { strcpy($$,$1); strcat($$,$3); }
           | stringExpr '-' stringExpr { strcpy($$,minus($1,$3)); }    
           | stringExpr '*' numberExpr { strcpy($$,mul($1,$3)); }
           | STRING
           ;

numberExpr : stringExpr '?' stringExpr { strcpy($$nr_of_aparitions($1,$3)); }
           | NUMBER
           ;

(我删除了你 expr1 中的空规则——我想这不是故意的。)

我想知道为什么你没有普通算术的语法规则,比如5 + 2,但也许这不是你计划的一部分。

如果您确实打算支持普通算术,那么您将需要考虑"foobar" - 1 + 1应该如何解释。此时,您可能需要查看 yacc/bison 的运算符优先级功能。

于 2013-01-24T15:16:46.570 回答