【问题标题】:Rascal error when specifying grammar指定语法时出现流氓错误
【发布时间】:2013-05-20 02:27:15
【问题描述】:

我在 rascal 中有一个用于指定玩具语法的简单文件

module temp

import IO;

import ParseTree;

layout LAYOUT = [\t-\n\r\ ]*;

start syntax Simple 
  =  A B ;

syntax A = "Hello"+ ("joe" "pok")* ;
syntax A= "Hi";
syntax B = "world"*|"wembly";
syntax B =    C | C C*   ;


public void main () {
println("hello");
iprint(parse(#start[Simple], "Hello Hello world world world"));
}

这很好,但是问题是我不想写

syntax B =    C | C C*   ;

我想写

syntax B =  (  C | C C*  )? 

但它被流氓拒绝为解析错误-即使所有

syntax B =  (  C  C C*  )? ;

syntax B =  (  C |  C*  )? ;

syntax B =    C | C C*   ;

接受很好。谁能向我解释我做错了什么?

【问题讨论】:

  • ps,您的布局定义会导致歧义,请添加跟随限制来解决此问题。

标签: grammar rascal


【解决方案1】:

序列符号(嵌套序列)总是需要括号中的无赖。元符号定义为

syntax Sym = sequence: "(" Sym+ ")" | opt: Sym "?" | alternative: "(" Sym "|" {Sym "|"}+ ")" | ... ;

因此,在您的示例中,您应该编写:

syntax B = (C | (C C*))?;

可能令人困惑的是,Rascal 使用 |签两次。一次用于分离顶级替代方案,一次用于嵌套替代方案:

syntax X = "a" | "b"; // top-level
syntax Y = ("c" | "d"); // nested, will internally generate a new rule: 
syntax ("c" | "d") = "c" | "d";

最后,正常的替代品有没有括号的序列,如:

syntax B 
  = C
  | C C*
  ;
// or less abstractly:
syntax Exp = left Exp "*" Exp
           > left Exp "+" Exp
           ;

顺便说一句,我们通常避免使用太多嵌套的正则表达式,因为它们是如此匿名,因此使解析树的解释变得更加困难。正则表达式的最佳用法是表达我们对内部结构不太感兴趣的词法语法。

【讨论】:

  • 太好了——我剩下的一个问题是'syntax B = C | C C* ;'解析很好 - 不需要括号 - 你可以扩展你的答案来涵盖这种情况吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-23
相关资源
最近更新 更多