Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.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
Parsing 处理以保留字开头的标识符_Parsing_Compiler Construction_Interpreter_Lexical Analysis - Fatal编程技术网

Parsing 处理以保留字开头的标识符

Parsing 处理以保留字开头的标识符,parsing,compiler-construction,interpreter,lexical-analysis,Parsing,Compiler Construction,Interpreter,Lexical Analysis,我目前正在编写自己的lexer,我想知道如何正确处理标识符以保留字开头的情况。目前,lexer将整个第一部分作为保留字进行匹配,然后将其余部分单独进行匹配,因为保留字是最长的匹配(“下面示例中的self”vs“s”) 例如规则: RESERVED_WORD := self IDENTIFIER_CHAR := [A-Z]|[a-z] 适用于: selfIdentifier “self”匹配为RESERVED\u WORD,“I”和“forwards”匹配为IDENTIFIER\u CHAR,

我目前正在编写自己的lexer,我想知道如何正确处理标识符以保留字开头的情况。目前,lexer将整个第一部分作为保留字进行匹配,然后将其余部分单独进行匹配,因为保留字是最长的匹配(“下面示例中的self”vs“s”)

例如规则:

RESERVED_WORD := self
IDENTIFIER_CHAR := [A-Z]|[a-z]
适用于:

selfIdentifier

“self”匹配为
RESERVED\u WORD
,“I”和“forwards”匹配为
IDENTIFIER\u CHAR
,当整个字符串应匹配为
IDENTIFIER\u CHAR
s

时,大多数lexer生成器的标准答案是匹配最长序列的正则表达式获胜。要打破两个匹配完全相同数量的正则表达式之间的平局,就是按照它们在定义文件中出现的顺序选择第一个正则表达式

您可以在lexer中模拟此效果。然后,“selfIdentifier”将被视为标识符


如果您正在编写一个高效的lexer,那么您将拥有一个基于当前字符类从一个状态分支到另一个状态的有限状态机。在这种情况下,您将有几个状态可以是终端状态,如果FSA无法切换到另一个状态,这些状态就是终端状态。您可以为每个这样的终端状态分配令牌类型;令牌类型将是唯一的。

如果该lexer是基于regexp的,那么像
(?!self)[a-z]+
这样的断言不可以吗?
标识符如何匹配标识符?标识符只匹配一个字符。如果它匹配多个字符,它应该是最长的匹配。@rici:我认为他的lexer实际上没有使用正则表达式;这些例子可能代表了他认为自己拥有的东西。而且,他在写下它们时犯了一个错误。我肯定他的意思是([A-Z]|[A-Z])+@irabaxter:也许吧,但OP回答这个问题可能会有帮助。在帖子中,人们知道最长匹配规则,但比较的匹配是
self
s
。如前所述,这是正确的,但它留下了标识符如何匹配标识符的问题。@rici您是对的,这是我问题中的一个错误。我现在已经编辑过了。当
保留字
匹配4个字符,而
标识符
只匹配一个字符时,这将如何工作?如果FSA可以转换到另一个状态,它会这样做。当它经过一个终端状态时,它会记录该状态。如果它到达的结束状态不是终端状态,它将为最后一个终端状态生成令牌,并相应地备份输入流。