递归规则
为了分析不定长的项目列表,需要使用递归规则,也就是用自身来定义自己。例如,下面这个例子分析一个可能为空的数字列表:
numberlist: /* empty */| numberlist NUMBER;
递归规则的实现完全依赖于具体需要分析的语法。下面这个例子分析一个通过逗号分隔的不为空的表达式列表,其中的expr在语法
的其它地方已经被定义:
exprlist: expr| exprlist ',' expr;
也可能存在交互的递归规则,它们彼此引用对方:
exp: term| term '+' term;
term: '(' exp ')'| VARIABLE;
任何递归规则或者交互递归规则组里的每个规则都必须至少有一条非递归的分支(不指向自身);否则,将没有任何途径来终止它所
匹配的字符串,这是一个错误。
%type声明
可以使用%type来声明非终结符的类型。该定义具有如下格式:
%type
每个type的名字必须在%union定义过。而每个name就是非终结符的名字。
%type被用来声明非终结符。对于记号而言,你需要使用%token,%left,%right和%nonassoc。