前瞻做了什么,为什么需要两个令牌

时间:2017-09-20 15:50:57

标签: javacc

我有这个:

void Identifier() : { Token t;}
{
t = <IDENTIFIER> {jjtThis.setValue(t.image);}
}

void AssignStatement() : { Token t;}
{
(
    LOOKAHEAD(2) Identifier() t = <ASSIGN>
    {
        jjtThis.addOp(t.image);
    }
)+ Expression()
}

Expression()调用比较,然后compare()调用logicExpression()等...(以运算符优先级排序) 我的令牌用于赋值运算符,算术和逻辑运算符,比较,分号,if,while,for statement等... 我知道LOOKAHEAD(2)会查看接下来的两个令牌,以决定选择哪个规则,但就我而言,我并不理解。

1 个答案:

答案 0 :(得分:1)

当解析需要做出选择时,它通常在下一个输入标记的基础上这样做。在这种情况下,它需要选择保持循环或离开循环。但通常的一个令牌是不够的,因为如果下一个令牌是<IDENTIFIER>,那么这可能是Identifier的开头或Expression的开头。但是,前瞻性的2个令牌就足够了:在接下来的两个令牌中<IDENTIFIER> <ASSIGN>,它应该保持在循环中,因为它不能成为表达式的开始。虽然表达可能只是<IDENTIFIER><ASSIGN>无法跟随AssignStatement

即。生成的AssignStatement代码看起来像这样,忽略了树构建代码。

call Identifier
if the next token is not an <ASSIGN> error
read the next token, call it t
while the next two tokens are <IDENTIFIER> <ASSIGN>
    call Identifier
    if the next token is not an <ASSIGN> error
    read the next token, call it t
call Expression