【问题标题】:How to use context free grammars?如何使用上下文无关语法?
【发布时间】:2019-12-14 16:53:11
【问题描述】:

有人可以帮助我使用上下文无关语法吗?到目前为止,我已经使用正则表达式从字符串中删除 cmets、阻止 cmets 和空行,以便可以使用它来计算 PLOC。这似乎非常慢,所以我一直在寻找另一种更有效的方法。

我看到了以下帖子:What is the best way to ignore comments in a java file with Rascal?

我不知道如何使用它,帮助也没有让我走得更远。当我尝试定义帖子中使用的行时,我立即收到错误消息。

lexical SingleLineComment = "//" ~[\n] "\n";

有人可以帮我解决这个问题,并解释一下如何设置这种上下文无关语法,然后实际提取所需的数据吗?

亲切的问候,

鲍勃

【问题讨论】:

    标签: rascal


    【解决方案1】:

    首先这会有所帮助:Rascal CFG 表示法中的 ~ 不在语言中,字符类的否定写法如下:![\n]

    在 Rascal 中使用上下文无关文法需要三个步骤:

    1. 写吧,比如这里Func语言的语法定义:http://docs.rascal-mpl.org/unstable/Recipes/#Languages-Func
    2. 用它来解析输入,像这样:

      // 这是基本的解析命令,但要注意它不会接受 TopNonTerminal 文本前后的空格和换行符:
      Prog myParseTree = parse(#Prog, "示例字符串");

      // 您可以直接对输入文件执行相同操作:
      Prog myParseTree = parse(#TopNonTerminal, |home:///myProgram.func|);

      //如果需要在程序前后接受布局,请使用“启动非终端”:
      start[Prog] myParseTree = parse(#start[TopNonTerminal], |home:///myProgram.func|); Prog myProgram = myParseTree.top;

      // 解析东西的简写:
      myProgram = [Prog] "示例"; myProgram = [Prog] |home:///myLocation.txt|;

    3. 获得树后,您可以开始使用visit/ deepmatch 从树中提取信息,或者根据需要编写递归函数。示例可以在这里找到:http://docs.rascal-mpl.org/unstable/Recipes/#Languages-Func,但这里也有一些常用的习惯用法,用于从解析树中提取信息:

      // 生成树中每个节点的源位置:
      myParseTree@\loc

      // 产生一组 Stat 类型的所有节点
      { 小号 | /Stat s := myParseTree }

      // 模式匹配 if-then-else 并绑定三个表达式并将它们收集在一个集合中:
      { e1, e2, e3 | (统计)`if then else end`

      // 收集所有子树的所有位置(每个解析树都是非终结类型,它是Tree的子类型。它使用|unknown:///| 表示小的子树为提高效率而未对它们进行注释,例如文字和字符类:
      [ t@\loc?|未知:///| | /Tree t := myParseTree ]

    这应该给你一个开始。我会去尝试一些东西,看看更多的例子。编写语法是一件好事,但它确实需要一些试错方法,例如编写正则表达式,但更是如此。

    对于您可能正在编写的语法,它会找到源代码 cmets 但将其余部分保留为“任何字符”,您将需要大量使用最长匹配消歧:

    lexical Identifier = [a-z]+ !>> [a-z]; // means do not accept an Identifier if there is still [a-z] to add to it; so only the longest possible Identifier will match.
    

    这种与上下文无关的语法被比喻称为“岛屿语法”,因为您将为要识别的部分(cmets 是“岛屿”)编写精确的规则,而将其余部分作为其他所有部分(其余部分)是“水”)。见https://dl.acm.org/citation.cfm?id=837160

    【讨论】:

      猜你喜欢
      • 2012-01-04
      • 2014-04-26
      • 2013-02-23
      • 2018-07-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多