指定语法时出现Rascal错误

时间:2013-05-24 13:10:10

标签: grammar rascal

我在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*  )? 

但它被rascal作为解析错误拒绝了 - 尽管所有的

syntax B =  (  C  C C*  )? ;

syntax B =  (  C |  C*  )? ;

syntax B =    C | C C*   ;

被接受罚款。谁能向我解释我做错了什么?

1 个答案:

答案 0 :(得分:2)

序列符号(嵌套序列)在rascal中始终需要括号。元符号定义为

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
           ;
顺便说一句,我们通常避免使用太多嵌套的正则表达式,因为它们是如此匿名,因此使得解析解析树更加困难。正则表达式的最佳用法是表达词法语法,无论如何我们对内部结构不太感兴趣。