Parsing 脚本语言的词法分析

Parsing 脚本语言的词法分析,parsing,scripting,analysis,analyzer,lexical,Parsing,Scripting,Analysis,Analyzer,Lexical,我正在尝试为资源API创建一个简单的脚本。我有一个资源API,主要是以结构化的方式创建游戏资源。我想要的是处理这个API,而不需要在每次需要资源时创建C++程序。所以我们(我和我的大学讲师)决定创建一个简单的脚本来创建/编辑资源文件,而无需每次编译。还有一些其他不相关的因素,我需要一个命令行界面,而不是GUI程序 无论如何,下面是脚本示例: <path>.<command> -<options> /Graphics[3].add "blabla.png" 我

我正在尝试为资源API创建一个简单的脚本。我有一个资源API,主要是以结构化的方式创建游戏资源。我想要的是处理这个API,而不需要在每次需要资源时创建C++程序。所以我们(我和我的大学讲师)决定创建一个简单的脚本来创建/编辑资源文件,而无需每次编译。还有一些其他不相关的因素,我需要一个命令行界面,而不是GUI程序

无论如何,下面是脚本示例:

<path>.<command> -<options>
/Graphics[3].add "blabla.png"
我不知道这种语法是否混乱。有5种不同的可能性,它们是:

String
"String"
Number
String[Number]
"String"[Number]
它必须以“/”符号开头,如果它是唯一的符号,我将接受它作为根

现在我的问题是如何从词汇上分析这个脚本?有什么特别的方法吗?我的词法分析器应该做什么和不应该做什么(我读过一些词法分析器在某种程度上也做语法分析)。你认为语法等在技术上合适吗?我应该使用什么样的解析方法(递归下降、LL等)?我正在努力使它成为技术上合适的作品。它不是商业性的,所以我有时间,这样我可以更好地学习词汇分析和语法分析。我不想使用解析器库

我的词法分析器应该做什么,不应该做什么?

它应当:

  • 识别代币
  • 忽略可忽略的空白和注释(如果有)
  • 或者,跟踪源位置以生成有意义的错误消息
它不应该试图解析输入,尽管对于这样一种简单的语言来说,这是非常诱人的

据我所见,您拥有以下代币:

  • 标点符号:
    /
    ,线性空白,新行
  • 数字
  • 不带引号的字符串(通常称为“原子”或“ID”)
  • 带引号的字符串(可能与不带引号的字符串的标记类型相同)
我不确定
-options
的语法是什么,但这可能包括更多的可能性

选择返回
线性空白
(即仅由制表符和空格组成的序列)作为标记有点可疑;它使语法变得相当复杂,特别是因为可能有空格不可忽略的地方,例如行首和行尾。但我有一种直觉,即您不希望在路径中使用空格,并且您计划在命令名及其参数之间使用空格。也就是说,您希望禁止:

/left /right[3] .whimper "hello, world"
/left/right[3].whimper"hello, world"
但也许我错了。也许你很乐意接受这两个。这会更简单,因为如果您同时接受这两种格式,那么您可以完全忽略线性空白

顺便说一句,经验表明,使用新行分隔命令可能会很尴尬;迟早你会需要将一个命令分成两行,以避免不得不购买一个额外的监视器来查看整行。将
\
作为要继续的行的最后一个字符的约定(bash和C预处理器等使用)是可能的,但可能会导致恼人的错误(例如在
\
后面有一个不可见的空格,从而阻止它真正继续行)


下面是100%的个人意见,免费提供。所以,不管它值多少钱,都要接受它

我正在努力使它成为技术上合适的工作。它不是商业性的,所以我有时间,这样我可以更好地学习词汇分析和语法分析。我不想使用解析器库。

在我看来,这里有一个矛盾。或者可能有两个矛盾

技术上合适的工作将使用标准工具;至少有一个词法生成器,可能还有一个解析器生成器。这是因为,如果使用得当,提供给工具的词汇和语法描述将准确记录实际语言,并且工具保证所需语言是实际识别的语言。编写特别的代码,即使是简单的词法识别器和递归下降解析器,尽管它可能很优雅,但它的自文档化程度较低,可维护性较差,并且提供的正确性保证也较少。因此,最佳做法是“使用标准工具”

其次,我不同意你的导师(如果我根据你的评论正确理解了他们的建议)的观点,即编写临时词法分析器和语法分析器有助于理解词法和语法分析理论。事实上,这可能适得其反。自下而上的语法分析在理论上和实践上都非常优雅,几乎不可能手工编写,也完全不可能阅读。因此,许多程序员更喜欢使用递归下降或普拉特解析器,因为他们理解代码。然而,这种解析器不如自底向上的解析器强大(特别是GLR或Earley解析器,它们是完全通用的),它们的使用会导致不必要的语法妥协

理解正则表达式不需要编写正则表达式库。这些库抽象掉了笨拙的实现细节(有很多,它们真的很笨拙),让您专注于创建和使用正则表达式的本质

同样,为了理解如何用C语言编程,你不需要编写编译器。在你掌握了C语言的良好基础之后,你可以通过理解它如何翻译成机器代码来提高你的理解能力(也许),但除非你计划从事编译编写工作,了解模糊优化算法的细节不会让你成为一个更好的程序员。或者,至少,他们不是你议程上的第一位

类似地,一旦您真正理解了正则表达式,您可能会发现编写一个库很有趣。或者不是——你可能会觉得非常沮丧,在几个月的努力工作后放弃了。不管怎样,你
/left /right[3] .whimper "hello, world"
/left/right[3].whimper"hello, world"