如何在JavaCC中对令牌执行否定的LOOKAHEAD检查? [英] How to implement a negative LOOKAHEAD check for a token in JavaCC?

查看:146
本文介绍了如何在JavaCC中对令牌执行否定的LOOKAHEAD检查?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在实现JavaScript / ECMAScript 5.1 JavaCC解析器。我最近学习了关于 LOOKAHEAD s的信息

I currently implementing a JavaScript/ECMAScript 5.1 parser with JavaCC. I recently learned about LOOKAHEADs which are handy here as the grammar is not fully LL(1).

我在ECMAScript语法中看到的一件事是负超前检查,例如以下 ExpressionStatement 生产:

One of the things I see in the ECMAScript grammar is "negative lookahead check", like in the following ExpressionStatement production:

ExpressionStatement :
    [lookahead ∉ {{, function}] Expression ;

所以我可能需要类似 LOOKAHEAD(!( { | function)),但在此语法中不起作用。

So I'll probably need something like LOOKAHEAD(!("{" | "function")) but it does not work in this syntax.

我的问题是,如何实现此否 LOOKAHEAD 在JavaCC中?

My question is, how could I implement this "negative LOOKAHEAD" it in JavaCC?

在阅读 LOOKAHEAD MiniTutorial 我认为像 getToken(1).kind!= FUNCTION 可能是我需要的,但是我不太确定。

After reading the LOOKAHEAD MiniTutorial I think that an expression like getToken(1).kind != FUNCTION may be what I need, but I am not quite sure about it.

推荐答案

对于您提供的示例,我

ExpressionStatement的产生不是解决问题的地方,因为别无选择

The production for ExpressionStatement is not the place to tackle the problem as there is no choice.

void ExpressionStatement() : {} { Expression() ";" }

如果在表达式语句和块之间还是在表达式之间进行选择,就会出现问题语句和函数声明(或两者)。

The problem will arise where there is a choice between an expression statement and a block or between an expression statement and a function declaration (or both).

例如在Statement中,您会发现

E.g. in Statement you will find

void Statement() :{} {
    ...
|
    Block()
|
    ExpressionStatement() 
|   ...
}

发出警告,因为两个选择都可以以 {开头。您有两个选择。一种是忽略警告。只要Block排名第一,将采取第一选择,一切都会好起来。第二种选择是使用超前规范抑制警告。像这样:

gives a warning because both choices can start with a "{". You have two options. One is to ignore the warning. The first choice will be taken and all will be well, as long as Block comes first. The second choice is to suppress the warning with a lookahead specification. like this:

void Statement() :{} {
    ...
|
    LOOKAHEAD("{") Block()
|
    ExpressionStatement() 
|   ...
}

从某种意义上说,语法向前看是积极的-如果X则采用此替代方法。

Syntactic look ahead is, in a sense positive -- "take this alternative if X".

如果您确实想要一个否定的符号,即,如果不是X则采用此替代方法-向前看

If you really want a negative --i.e., "take this alternative if not X"-- look ahead it has to be semantic.

对于语句,您可以编写

void Statement() :{} {
    ...
|
    LOOKAHEAD({!(getToken(1)==LBRACE)}) ExpressionStatement() 
|   
    Block()
}

我确保这是最后两个替代方案,因为否则您需要在阻止ExpressionStatement()的一组令牌中包括更多令牌,例如

I made sure that these are the last two alternatives since otherwise you'd need to include more tokens in the set of tokens that block ExpressionStatement(), e.g. it should not be chosen if the next token is an "if" or a "while" or a "for", etc.

总的来说,你过得更好可以时使用句法前瞻。通常,它更直接,也更难弄乱。

On the whole, you are better off using syntactic lookahead when you can. It is usually more straight forward and harder to mess up.

这篇关于如何在JavaCC中对令牌执行否定的LOOKAHEAD检查?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆