非法争论:小语言的ParseTree错误

时间:2015-10-11 12:57:57

标签: rascal

我现在坚持这个问题一段时间了,希望你能提供帮助。我有以下(缩短的)语言语法:

lexical Id  = [a-zA-Z][a-zA-Z]* !>> [a-zA-Z] \ MyKeywords;
lexical Natural = [1-9][0-9]* !>> [0-9];
lexical StringConst = "\"" ![\"]*  "\"";

keyword MyKeywords = "value" | "Male" | "Female";

start syntax Program = program:  Model* models;
syntax Model = Declaration;
syntax Declaration = decl: "value" Id name ':' Type t "=" Expression v ;
syntax Type = gender: "Gender";
syntax Expression = Terminal;
syntax Terminal = id: Id name
                | constructor: Type t '(' {Expression ','}* ')'
                | Gender;
syntax Gender = male: "Male"
              | female: "Female";

alias ASLId = str;
data TYPE = gender();
public data PROGRAM = program(list[MODEL] models); 
data MODEL = decl(ASLId name, TYPE t, EXPR v);
data EXPR = constructor(TYPE t, list[EXPR] args) 
          | id(ASLId name)                
          | male()
          | female(); 

现在,我正在尝试解析:

value mannetje : Gender = Male  

这解析很好,但内爆失败,除非我从语法中删除id:Id名称和它的构造函数。我预计/ MyKeywords会阻止这种情况,但不幸的是它没有。你能帮我解决这个问题,还是指出我如何调试?我在调试Concrete和Abstract语法时遇到了一些麻烦。

谢谢!

2 个答案:

答案 0 :(得分:2)

它似乎根本没有解析(如果我尝试你的例子,我得到一个ParseError)。

其中一个问题可能是您没有定义布局。这会导致ParseError给出示例。最简单的修复之一是在lang :: std :: Layout中扩展标准布局。此布局定义所有默认的空格(和注释)字符。 有关非终结者的更多信息,请参阅here

我冒昧地将你的例子进一步简化,以便解析和内爆工作。我删除了一些未使用的非终结符号以保持解析树更简洁。你可能想要在你的程序中获得更多的声明,但我把它留给你。

extend lang::std::Layout;

lexical Id  = ([a-z] !<< [a-z][a-zA-Z]* !>> [a-zA-Z]) \ MyKeywords;

keyword MyKeywords = "value" | "Male" | "Female" | "Gender";

start syntax Program = program:  Declaration* decls;

syntax Declaration = decl: "value" Id name ':' Type t "=" Expression v ;

syntax Type = gender: "Gender";

syntax Expression
    = id: Id name
    | constructor: Type t '(' {Expression ','}* ')'
    | Gender
    ;

syntax Gender 
    = male: "Male"
    | female: "Female"
    ;

data PROGRAM = program(list[DECL] exprs); 
data DECL = decl(str name, TYPE t, EXPR v);
data EXPR = constructor(TYPE t, list[EXPR] args) 
          | id(str name)                
          | male()
          | female()
          ; 

data TYPE = gender();

答案 1 :(得分:2)

两件事:

  • ADT的名称应与非终结名称相对应(您有不同的情况,而EXPR不是表达式)。这是implode现在如何开展工作的唯一途径。将数据decls放在他们自己的模块中并按如下方式进行内爆:implode(#AST::Program, pt)其中pt是解析树。

  • 语法含糊不清:\ MyKeywords仅应用于标识符语法的尾部。使用修复:([a-zA-Z][a-zA-Z]* !>> [a-zA-Z]) \ MyKeywords;

这对我有用(语法不变,除了修复):

module AST

alias ASLId = str;
data Type = gender();
public data Program = program(list[Model] models); 
data Model = decl(ASLId name, Type t, Expression v);
data Expression = constructor(Type t, list[Expression] args) 
      | id(ASLId name)                
      | male()
      | female();