Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/api/5.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
Regex 词法分析器中标识符的正则表达式帮助_Regex_Compiler Construction_Lexer_Regular Language_Computation Theory - Fatal编程技术网

Regex 词法分析器中标识符的正则表达式帮助

Regex 词法分析器中标识符的正则表达式帮助,regex,compiler-construction,lexer,regular-language,computation-theory,Regex,Compiler Construction,Lexer,Regular Language,Computation Theory,我正在尝试制作一个lexer,我不想使用lex文件,因为我想学习,所以现在我要为标识符创建正则表达式,满足以下约束条件: “\”不能是标识符。 总是用一些字母下划线。 Id至少包含一个下划线。 下划线不能是id的最后一个符号。 必须有一个或多个数字。 不是以数字开头 到目前为止,我已经完成了正则表达式: ([_a-zA-Z]*[a-zA-Z][a-zA-Z]*[_a-zA-Z]*[0-9][0-9]*[_a-zA-Z]*)* 问题是我无法对标识符中的“至少一个”执行约束,我无法使其更复杂,因为

我正在尝试制作一个lexer,我不想使用lex文件,因为我想学习,所以现在我要为标识符创建正则表达式,满足以下约束条件:

“\”不能是标识符。 总是用一些字母下划线。 Id至少包含一个下划线。 下划线不能是id的最后一个符号。
必须有一个或多个数字。 不是以数字开头

到目前为止,我已经完成了正则表达式:

([_a-zA-Z]*[a-zA-Z][a-zA-Z]*[_a-zA-Z]*[0-9][0-9]*[_a-zA-Z]*)*

问题是我无法对标识符中的“至少一个”执行约束,我无法使其更复杂,因为我必须将此正则表达式转换为非确定性有限自动机,所以请您提供帮助。

您已指定以下约束:

  • 可能包含字母、数字和下划线
  • 必须至少包含一个数字
  • 必须至少包含一个下划线
  • 不能以下划线结尾
  • 不能以数字开头
“至少一个X”类型的约束对应于状态机中的状态。因为我们有两个这样的约束,所以有2*2=4个状态来管理我们是否仍然需要数字或下划线。我将把各州缩写为:

  • DU–需要数字,需要下划线
  • Du–需要数字,有下划线
  • dU–有数字,需要下划线
  • du–有数字,有下划线
我们现在可以创建一个状态转换表:

STATE TRANSITIONS
      _  0-9 a-zA-Z
----- -- --- ------
 DU   Du dU  DU
 Du   Du du  Du
 dU   du dU  dU
 du   du du  du
其中,
DU
是启动状态。对于第一个和最后一个状态转换,您有额外的特殊要求。此外,只能从
du
状态到达结束状态。实际上,
du
本身可能是结束状态,如果它不是通过
\uu
输入到达的。连同这些其他需求,我们得到以下状态转换表。启动状态为
S
,终端状态用
*
标记。我忽略了非法转换

STATE TRANSITIONS
       _  0-9 a-zA-Z
----- --- --- -----
 S    Du   -   DU
 DU   Du  dU   DU
 Du   Du  du   Du
 dU   du' dU   dU
*du   du' du   du
 du'  du' du   du
状态
du'
是“我们已经看到了我们需要的一切,但是最后一个符号是下划线,所以我们不能在这里结束”——状态。此状态表不会强制任何下划线后面跟一个字母,但您应该能够使用类似的方法自己添加该字母。状态表对应于DFA,但我怀疑您是否可以通过使用NFA来简化它

我们现在可以将这个状态机转换为正则表达式,但这有点繁琐,因为我们有六个状态(推测:所呈现的状态机已经是最小的)。通过迭代地将状态转换组合成正则表达式片段并消除状态,我们最终得到了以下正则表达式:

([_][_a-zA-Z]*[0-9]|[a-zA-Z][a-zA-Z]*([_][_a-zA-Z]*[0-9]|[0-9][0-9a-zA-Z]*[_]+[0-9a-zA-Z]))[0-9a-zA-Z]*([_]+[0-9a-zA-Z]+)*
除非我弄错了。在这一点上很有可能


对于这种验证,使用正则表达式很麻烦。相反,使用更简单的模式,如
[\u a-zA-Z][\u 0-9a-zA-Z]+
,然后检查匹配的字符串是否包含数字和下划线,并遵循有关下划线的其他规则。如果标识符在输入语言中以某种方式进行分隔(例如,由空格或其他非标识符字符分隔),则此操作非常有效。

刚刚编辑了我的描述它很容易在字符串中要求“至少一个A”:只需说
[AB]*A[AB]*
。所有正则表达式都可以转换为NFA和DFA-您在这里没有使用任何会使您的语言成为非正则语言的正则表达式功能。是的,我知道,但正如您所看到的,还有其他与下划线相关的约束,现在R.A有点复杂,我找不到它应该放下划线的位置,也找不到应该放重复路径的位置仅供参考,
XX*
可以缩短为
X+
(这个模式可以在正则表达式中找到两次)。你说的“下划线总是带字母”到底是什么意思?你是说每个下划线后面都必须跟一个字母吗?或者你的意思是每个下划线必须跟在一个字母后面还是跟在一个字母后面?你颠倒了整个过程来完成这个简单的任务为什么?我很感激你的回答,但是curious@Zulqurnainjutt仅仅因为正则表达式和自动机是等价的,并不意味着我总是喜欢使用正则表达式。看看最后一个正则表达式:它既长又复杂,我永远也不可能“像那样”理解它。然而,当我们用状态和状态转换来表达这个问题时,它有一个非常简洁和简单的描述。我发现状态机更容易使用。(我最近参加了一门关于正式语言和状态机的课程,我们在这门课程中也遇到了类似的问题,这也有帮助。)你的答案是关于标识符“d_3__abc2e”,为什么?因为在第二个下划线之后,右边有一个运算符“u”,左边有一个“digit”,字母在哪里?那么它不应该接受它。