我正在尝试制作一个词法分析器,我不想使用 lex 文件,因为我想学习,所以说到我想为下面的标识符做正则表达式约束:
' __'不能是标识符。 总是用一些字母强调。 Id包含至少一个下划线。 下划线不能是id的最后一个符号 必须有一个或多个数字。 不是从Digit开始。
现在我已经完成了正则表达式:
([_a-zA-Z]*[a-zA-Z][a-zA-Z]*[_a-zA-Z]*[0-9][0-9]*[_a-zA-Z]*)*
问题是我无法对至少一个_'进行约束。在标识符中,我不能使它更复杂,因为我必须将这个正则表达式转换为非确定性有限自动机,所以你能帮忙。
答案 0 :(得分:2)
您已指定以下约束:
“至少一个X”类型约束对应于状态机中的状态。由于我们有两个这样的约束,因此有2 * 2 = 4个状态可以管理我们是否还需要数字或下划线。我将缩写状态:
我们现在可以创建一个状态转换表:
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
如果没有通过_
输入达到,则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'
州([_][_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]+)*
是“我们已经看到了我们需要的一切,但最后一个符号是下划线,所以我们不能在这里结束” - 状态。此状态表不强制任何下划线后跟一个字母,但您应该能够使用类似的方法自己添加。状态表对应于DFA,但我怀疑您可以使用NFA来简化它。
我们现在可以将这个状态机转换为正则表达式,但由于我们有六个状态(猜想:所呈现的状态机已经很小),这有点单调乏味。通过迭代地将状态转换组合成正则表达式片段并消除状态,我们最终得到了这个正则表达式:
[_a-zA-Z][_0-9a-zA-Z]+
好吧,除非我弄错了。在这一点上很可能。
对于这种验证,使用正则表达式很麻烦。相反,使用更简单的模式,如IllegalStateException
,然后检查匹配的字符串是否包含数字和下划线,并遵循关于下划线的其他规则。如果标识符以某种方式用输入语言分隔,例如,这可以很好地工作。通过空格或其他非标识符字符。