我正在使用Java15语法,并且有几个关于Rascal解析器如何工作的问题以及为什么有些东西不起作用。给定一个具体的语法:解析,匹配和关键字
module tests::Concrete
start syntax CompilationUnit =
compilationUnit: TypeDec* LAYOUTLIST
;
syntax TypeDec =
ClassDec
;
syntax ClassDec =
\class: ClassDecHead ClassBody
;
syntax ClassDecHead =
"class" Id
;
syntax ClassBody =
"{" ClassBodyDec* "}"
;
syntax ClassBodyDec =
ClassMemberDec
;
syntax ClassMemberDec =
MethodDec
;
syntax MethodDec =
\method: MethodDecHead
;
syntax MethodDecHead =
ResultType Id
;
syntax ResultType =
\void: "void"
;
syntax Id =
\id: [A-Z_a-z] !<< ID \ IDKeywords !>> [0-9A-Z_a-z]
;
keyword Keyword =
"void"
;
keyword IDKeywords =
"null"
| Keyword
;
lexical LAYOUT =
[\t-\n \a0C-\a0D \ ]
;
lexical ID =
[A-Z_a-z] [0-9A-Z_a-z]*
;
layout LAYOUTLIST =
LAYOUT* !>> [\t-\n \a0C-\a0D \ ] !>> ( [/] [*] ) !>> ( [/] [/] ) !>> "/*" !>> "//"
;
的AST定义:
module tests::Abstract
data Declaration =
\compilationUnit(list[Declaration] body)
| \package(ID name)
| \import(ID name)
| \class(ID name, list[Declaration] body)
| \method(Type ret, ID name)
;
data Type =
\void()
;
data ID =
\id(str id)
;
和驱动程序加载文件:
module tests::Load
import Prelude;
import tests::Concrete;
import tests::Abstract;
public Declaration load(loc l) = implode(#Declaration, parse(#CompilationUnit, l));
我发现在一些古怪什么是实际工作,什么不是。如果我拿方案:
class A {
}
这解析预期为: 但是解析和构建AST节点为类的内部方法被证明是有点毛。鉴于方案:
class A {
void f
}
这产生了一个"Cannot find a constructor for Declaration"
错误。如果我修改语法是:
syntax MethodDecHead =
ResultType
;
的AST是:
| \method(Type ret)
我能够得到的树我希望:compilationUnit([class(id("A"),[method(void())])])
我有很多对这里发生的事情感到困惑,如何处理关键字以及导致此行为的原因。
除此之外,如果我不将LAYOUTLIST
添加到start syntax
生产的末尾,我会在任何时候尝试从文件读取时获得ParseError
。
还不如贴在这里的整个示例文件。看起来足够小 – jurgenv