首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在PLY中处理模糊令牌的适当方法

在PLY中处理模糊令牌的适当方法
EN

Stack Overflow用户
提问于 2022-08-24 20:30:47
回答 1查看 47关注 0票数 0

我正在实现一种现有的脚本语言,部分是作为一个玩具项目来实现的,部分是为了编写我自己使用该语言的程序的实现。我遇到的一个问题是,我有一些在规范方面重叠但在使用时更清楚的结构:

代码语言:javascript
复制
 Variables - r'[A-Za-z0-9_]+'      # Yes, '456' is a valid variable name
 Numbers - r'-?[0-9]+(\.[0-9]+)?'
 Macros - r'\#[A-Za-z0-9_]+'
 Field Reference - r'(this\.)?([A-Za-z]+\.)*[A-Za-z]+'
 Tag reference - r'[A-Za-z0-9_]+\.[A-Za-z0-9_]*\??'

这主要是可行的,但是,例如,"456“可以是一个数字或一个变量。"34.567“可能是一个数字或标记引用(脚本语言的文档说用数字启动标识符是个坏主意,但并不完全禁止)。是否有一个很好的方法来处理标记的潜在模糊性?目前,我正在将前者标记为变量,将后者标记为一个数字,并在解析器中稍后处理,但感觉非常笨拙。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-08-25 15:53:30

标记器是否需要区分变量、数字、字段引用和标记引用?据推测,解析器将能够通过查阅其声明变量的符号表,并可能通过考虑使用令牌的上下文,来决定特定令牌属于哪些类别。如果是这样的话,那么您只需为所有四种情况返回一个令牌,这将简化您的lexer,可能还可以简化您的语法。

有一个解析器设计的一般原则,这个原则从来没有得到足够的强调,所以我在这里用粗体表示:

每个解析器组件都应该完成区分正确输入所需的绝对最小工作量。

换句话说,如果唯一的可能性是唯一正确的解析和输入错误,并且很难在适用的点上决定,那么就把这个决定传递到下一个阶段,那里有更多的信息。只有做必要的工作来区分两个或更多不同的正确输入。

例如,这适用于在解析器中尝试进行类型检查。这是一个失败的命题;在完成语义分析并知道所有标识符所引用的内容之前,没有足够的信息可以正确地进行。更重要的是,它不会给解析器(或lexer)带来任何好处,因为它不会影响正确的输入的解析方式;它所做的就是让您识别某些(而不是全部)不正确的输入。根据上述原则,你不应该尝试。

在解析过程中,这个原则一次又一次地出现。总是有一种诱惑,试图使错误检测在解析过程中过早地“更加精确”。抵抗!只有当您有足够的信息可靠地执行错误检测时,才执行错误检测。无论如何,你必须在那个时候做这件事,所以你不能通过尝试更早地做一些事情来节省任何东西。早期检测可能会使失败的解析减少几微秒,但是解析不正确输入的速度并不重要。总是对正确的输入进行优化。

这也适用于为语法编写语法,而这些语法并不容易精确地压缩为单向查找语法。可以让一个不正确的输入潜入解析,然后在语义分析期间检测它。例如,您可以尝试检测内置函数调用是否有正确的参数数。但何必费心呢?让一个参数太多或太少的调用进行语义分析并不会产生任何歧义。还有很多其他的例子。

让错误流到语义分析中的其他巨大好处是,生成准确的错误消息要容易得多,这对最终用户很有用,而且更容易进行错误恢复,因此您可以继续处理输入,并在一次运行中提供多个错误和警告,这是用户会欣赏的另一个功能。

每个准则都有例外,所以我并不是说这是一个绝对的规则。例如,在COBOL中,一些操作符根据其数据类型有不同的解析先例。(我希望,今天没有一个明智的语言设计师会做出这种野蛮的举动,但你确实需要将它考虑到遗留解析器中。)只有在正确的输入之间不产生歧义的情况下,才能将决策传递到行尾。但你应该时刻记住这条准则。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73479135

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档