脚本语言的词汇分析

时间:2013-07-11 15:43:24

标签: parsing scripting analysis analyzer lexical

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

无论如何,这是脚本示例:

<path>.<command> -<options>
/Graphics[3].add "blabla.png"

我没有设计这种脚本语言,API的所有者。 '。'之前的部分你可以猜到的是'。'之后的路径和部分。是实际命令和一些选项,标志等。作为第一步,我尝试创建左侧部分的语法,因为我认为我可以在搜索有关词法分析器和解析器的信息时使用它。问题是我在解析和编程语言时缺乏经验,我不确定它是否正确。这里有一些左侧的例子和语法。

dir -> '/' | '/' path
path -> object '/' path | object
object -> number | string '[' number ']'

如果这个语法可以乱七八糟,我不知道。有5种不同的可能性,它们是:

String
"String"
Number
String[Number]
"String"[Number]

它必须以'/'符号开头,如果它是唯一的符号,我会接受它作为Root。

现在我的问题是如何在词汇上分析这个脚本?有特殊方法吗?我的词法分析器应该做什么和不做什么(我读过一些词法分析器也做了句法分析到一定程度)。你认为语法等在技术上是否合适?我应该使用什么样的解析方法(Recursive Descent,LL等)?我试图让它在技术上合适的工作。这不是商业,所以我有时间,因此我可以更好地学习词法分析和解析。我不想使用解析器库。

1 个答案:

答案 0 :(得分:3)

  

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

它应该:

  • 识别代币
  • 忽略可忽略的空白和评论(如果有这样的事情)
  • 可选地,跟踪源位置以产生有意义的错误消息。

它不应该尝试解析输入,尽管用这么简单的语言会非常诱人。

从我所看到的,你有以下令牌:

  • 标点符号:/.,线性空格,换行符
  • 不带引号的字符串(通常称为&#34; atoms&#34;或&#34; id&#34;)
  • 引用字符串(可能与未加引号的字符串具有相同的标记类型)

我不确定-options的语法是什么,但这可能包含更多可能性。

选择返回linear-white-space(即仅包含制表符和空格的序列)作为令牌有点值得怀疑;它使语法变得相当复杂,特别是因为可能存在空白可忽略的地方,例如行的开头和结尾。但我有直觉,你不想在路径中允许空格,并且你打算在命令名和它的参数之间要求它。也就是说,你想要禁止:

/left /right[3] .whimper "hello, world"
/left/right[3].whimper"hello, world"

但也许我错了。也许你很高兴接受这两个。这会更简单,因为如果你接受两者,那么你可以完全忽略线性空格。

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


从这里下来是100%的个人意见,免费提供。所以要把它当作它的价值。

我正在努力使其在技术上合适。它没有商业化,所以我有时间,因此我可以更好地学习词法分析和解析。我不想使用解析器库。

在我看来,这里存在矛盾。或者也许是两个矛盾。

技术上合适的工作将使用标准工具;至少是一个词法生成器,可能还有一个解析器生成器。它会这样做,因为正确使用,提供给工具的词汇和语法描述准确地记录了实际语言,并且工具保证所需语言是实际识别的语言。编写即席代码,甚至是简单的词法识别器和递归下降解析器,对于它可以优雅的所有内容,自我记录较少,可维护性较差,并且提供较少的正确性保证。因此,最佳做法是使用标准工具&#34;。

其次,我不同意你的导师(如果我根据你的评论正确地理解他们的提议),那就是编写特设词法分析器和解析器有助于理解词法和解析理论。事实上,它可能适得其反。自下而上的解析在理论和实践上都非常优雅,几乎不可能用手写,完全不可能阅读。因此,许多程序员喜欢使用递归下降或Pratt解析器,因为他们理解代码。但是,这样的解析器不像自下而上的解析器(特别是GLR或Earley解析器,它们完全通用)那么强大,并且它们的使用会导致不必要的语法上的妥协。

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

以同样的方式,你不需要编写编译器来理解如何在C中编程。之后你有一个很好的C基础,你可以提高你的理解(也许)通过了解它如何转换为机器代码,但除非你计划编写编写器的职业,否则了解模糊优化算法的细节并不会使你成为更好的程序员。或者,至少,他们并不是你议程上的第一个。

同样,一旦你真正理解正则表达式,你可能会发现编写一个有趣的库。或者不是 - 经过几个月的艰苦努力,你会发现它令人难以置信的沮丧和放弃。无论哪种方式,您都会更喜欢现有的库。但要先学会使用现有的库。

与解析器生成器相同。如果您想学习如何将编程语言的想法转换为精确且可实现的内容,请学习如何使用解析器生成器。只有在掌握了解析理论之后,你才应该考虑专注于低级实现。