我现在坚持这个问题一段时间了,希望你能提供帮助。我有以下(缩短的)语言语法:
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语法时遇到了一些麻烦。
谢谢!
答案 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();