Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/352.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/xamarin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
区分右移(>;)和Java泛型_Java_Compiler Construction_Flex Lexer_Lexer - Fatal编程技术网

区分右移(>;)和Java泛型

区分右移(>;)和Java泛型,java,compiler-construction,flex-lexer,lexer,Java,Compiler Construction,Flex Lexer,Lexer,我正在用flex为java编写一个lexer。 java规范说: “每一步都使用尽可能长的翻译,即使结果最终不能生成正确的程序,而另一个词法翻译会。有一个例外:如果词法翻译发生在类型上下文中(§4.11)并且输入流有两个或多个连续的>字符,后跟一个非->字符,则每个>字符必须转换为数字比较运算符>“ 因此,我如何区分右移运算符和类似于中的运算符?最初的Java泛型方案(JSR-14)要求修改参数化类型的Java语法,以便在可能使用多个闭角括号的上下文中接受>和>。(我找不到JSR-14的有用权威

我正在用flex为java编写一个lexer。 java规范说:

“每一步都使用尽可能长的翻译,即使结果最终不能生成正确的程序,而另一个词法翻译会。有一个例外:如果词法翻译发生在类型上下文中(§4.11)并且输入流有两个或多个连续的>字符,后跟一个非->字符,则每个>字符必须转换为数字比较运算符>“


因此,我如何区分右移运算符和类似于
中的运算符?

最初的Java泛型方案(JSR-14)要求修改参数化类型的Java语法,以便在可能使用多个闭角括号的上下文中接受
>
>
。(我找不到JSR-14的有用权威链接,但Gilad Bracha的网站上仍然可以找到;语法修改如第2.3节所示。)

据我所知,这些修改从未正式纳入任何Java标准;最终,JLS8将这一变化纳入了您在问题中引用的词汇分析描述中。(参见,它还复制了最初提出的复杂语法。)

Bracha等人提出的语法修改是可行的,但您可能会发现,它们使合并其他语法更改变得更加复杂。(我还没有深入研究过这个问题,所以对于当前的Java语言规范来说,这实际上可能不是一个问题。但对于未来的版本来说,这仍然可能是一个问题。)

虽然上下文词汇分析确实允许在JLS中实际使用更简单的语法,但它肯定会给词汇分析带来困难。一种可能的方法是完全放弃词汇分析,使用;这当然会起作用,但在Bison/Flex模型中无法实现这一点。此外,您可能会发现,支持无扫描解析所需的一些修改还需要对已发布的语法进行非常重要的更改

另一种可能性是使用来自解析器的词汇反馈,方法是合并中间规则操作(mid-rule actions,MRA),在输入和退出类型上下文时打开和关闭“类型上下文”标志。(在§4.11中有一个完整的类型上下文列表,可用于查找语法中的适当位置。)如果您尝试此操作,请注意MRA的执行与词法分析并不完全同步,因为解析器通常需要一个前瞻标记来决定是否减少MRA。您通常需要在语法中比您想象的更早地放置MRA符号,以便它在需要时实际生效

另一种可能是永远不会将
>
>>
识别为令牌。相反,lexer可以返回两个不同的
标记,其中一个在下一个字符是
时使用:

>/>     { return CONJUNCTIVE_GT; }
>       { return INDEPENDENT_GT; }
  /* These two don't need to be changed. */
>>=     { return SHIFT_ASSIGN; }
>>>=    { return LONG_SHIFT_ASSIGN; }
然后,您可以修改语法以识别
>
>>
运算符,同时允许任何形式的
作为闭合角括号:

shift_op     : CONJUNCTIVE_GT INDEPENDENT_GT
long_shift_op: CONJUNCTIVE_GT CONJUNCTIVE_GT INDEPENDENT_GT
close_angle  : CONJUNCTIVE_GT | INDEPENDENT_GT
gt_op        : INDENPENDENT_GT /* This unit production is not really necessary */

这应该是可行的(尽管我还没有尝试过),但是Bison/Yacc操作符优先级机制不能很好地使用它,因为您不能为非终端声明优先级。因此,您需要使用带有显式运算符优先级规则的表达式语法,而不是带有优先级声明的模糊语法。

“那么,如何根据上下文区分右移位运算符和类似于
?”中的内容呢。右移是算术表达式的一部分,而泛型是构造函数调用、方法签名、类型或类定义的一部分。这里我想问的是如何在lexer(lex代码)中区分它们。如果扫描器只进行标记化,那么遇到的
与此无关。
是一个
,没有区别。语法正确性随后由解析器保证。但是,如果扫描器没有计算器,那么扫描器需要上下文信息,因为。@Turing85:不太需要。在大多数语言中,
>
是单个标记(如
>=
)。如果
>
是两个标记,语法会接受像
2>>3
或者甚至
2>/*这样的表达式,这是一个右移*/>3
,这通常是不受欢迎的。
long\u shift\u op
应该是
连接的
独立的,对吗?