我应该使用解析器/词法分析器吗?

时间:2009-12-18 00:31:32

标签: parsing string

我想知道像ANTLR这样的工具是否适合解析这些规则,或者它是否过度,我应该创建自己的解析器。

这是为了解析别人的格式,所以我无法改变它。这是为了娱乐和练习,所以不要担心太多。这些是描述语言中语音变化的规则。我引用the original author

  

声音变化格式

     

希望任何语言学家都熟悉规则的格式。例如,这是一个声音变化:

     

c/g/V_V

     

这条规则说要在元音之间改变c到g。 (我们将在下面看到如何概括此规则。)

     

更一般地说,声音变化如下所示:

     

x/y/z

     

其中x是要改变的东西,y是它改变的东西,z是环境。

     

z部分必须始终包含下划线_,表示更改的部分。这可以是全部,如

     

gn/nh/_

     

告诉程序无条件地用nh替换gn。

     

字符#代表单词的开头或结尾。所以

     

u/o/_#

     

表示将o替换为o,但仅限于单词的末尾。

     

中间(y)部分可以为空白,如

     

s//_#

     

这意味着s在结束单词时被删除。

     

变量

     

环境(z部分)可以包含变量,如上面的V。这些是在文件的顶部定义的。我使用大写字母,虽然这不是一个要求。变量只能是一个字符长。您可以定义声明声音变化所需的任何变量。例如。你可以将S定义为任何停止,或者将K定义为任何冠状,或任何其他。

     

所以变量定义和规则

     

F=ie   c/i/F_t

     

表示c在前元音之后和t之前变为i。

     

您也可以在前两部分中使用变量。例如,假设您已定义

     

S=ptc   Z=bdg   S/Z/V_V

     

这意味着停止ptc变为元音之间的浊音等价物bdg。在这种用法中,变量必须一对一对应 - p转到b,t转到d等。替换变量中的每个字符(此处为Z)给出输入变量中每个字符的转换值(此处为S) 。确保两个变量定义的长度相同!

     

变量也可以设置为固定值或删除。 E.g。

     

Z//V_V

     

说删除元音之间的浊音停止。

     

规则顺序

     

规则适用于列出的顺序。所以,用歌剧和规则这个词

     

p/b/V_V   e//C_rV

     

第一条规则发出声音,导致了obera;第二个删除辅音和intervocalic之间的e,导致obra。

     

-p命令行参数可以帮助调试规则,因为它会使输出准确显示应用于每个单词的规则。

     

环境中的可选元素

     

环境中的一个或多个元素可以用括号标记为可选。 E.g。

     

u/ü/_C(C)F

     

当你接着是一个或两个辅音然后是一个前元音时,要把你改成ü。

5 个答案:

答案 0 :(得分:2)

虽然您的语言很简单,但使用ANTLR有很多优点。

  1. 速度。生成的代码非常快。

  2. 简单。由于您使用的是更高级别的语言,因此小语法更改成本更低且更复杂。

  3. 扩展。由于您使用的是更高级别的语言,因此添加功能是一项成本较低的活动。

  4. 是的,你需要学习ANTLR。如果你的语法含糊不清,你需要学习shift-reduce和reduce-reduce冲突。这可能花费很多时间。

    许多问题是词汇扫描或解析问题。了解如何创建词法扫描程序和解析器是一项有用的技能。

答案 1 :(得分:1)

如果您的问题只是解析规则,那么您可能不需要解析器生成器。如你所说,所有的规则都是X / Y / Z形式,并且在任何语言中分割它们都非常容易。

如果我怀疑您正在创建一个可以读取规则并将其应用于文件的工具,那么问题就会复杂得多。

要使用解析器生成器,假设您有一组固定的规则,则必须以解析器生成器所需的格式将它们转换为一组语法生成并将它们提供给它。编译解析器生成器输出,您将获得一个能够根据这些规则转换文件的程序。鉴于您的规则似乎对上下文敏感(c/g/V_V),我建议寻找提供GLR(Tomita解析器)或PEG(解析Epression Grammars)的解析器生成器。

如果您的规则集没有修复,并且您的程序必须与要转换的文件一起阅读它们,那么您真正需要的是文本转换引擎。在这种情况下,您将把X / Y / Z规则转换为正确的格式,并将其与源文件一起提供给引擎。

假设您不想编写自己的引擎,可以查看通用宏处理器(M4Gema,...)或直接查看解释语言({{3} },perl,...)来帮助你。

例如在Gema中,您可以将c/g/V_V翻译成:

<vowel>c<vowel>=$1g$2
vowel:a=a;e=e;i=i;o=o;u=u;=@terminate

并在Lua中进入:

function rule1(s)
  return (string.gsub(s,"([aeiou])c([aeiou])","%1g%2"))
end

最后,这取决于您是否需要为给定的规则集创建内容,或者您​​是否需要能够阅读和解释任何规则集。

当然,在任何情况下,你都必须解析你的规则才能以正确的格式转换它们,但正如我在开头所说的那样,语法看起来非常简单,并且不能证明使用a解析器生成器。

答案 2 :(得分:0)

在我看来,使用解析工具是过度的,特别是如果您还不熟悉可以完成这项工作的工具。

答案 3 :(得分:0)

是否可以更改规则格式以使用已有的语法,该语法具有易于使用的解析器?

答案 4 :(得分:0)

首先回答问题:“这种语言是否有嵌套/递归模式?”

如果是,您至少需要一个无上下文语法的解析器。手动构建,或由一些解析器生成器生成。

如果不是,正则表达式就足够了。