具体的语法模式匹配可以进行哪些操作?
What operations are possible in concrete syntax pattern matching?
我正在尝试仅使用具体语法(无 AST)重写 java 代码。下一个代码有效:
CompilationUnit rewritePackage(CompilationUnit input) =
visit(input) {
case (PackageDeclaration) `package <{Identifier "."}+ N>;` =>
(PackageDeclaration) `package <{Identifier "."}+ N>.<Identifier s>;`
when s:= [Identifier] "othertest"
};
现在我想创建 {Identifier "."}+
以便将其插入到重写结果中:
CompilationUnit rewritePackage(CompilationUnit input) =
visit(input) {
case (PackageDeclaration) `package <{Identifier "."}+ N>;` =>
(PackageDeclaration) `package <{Identifier "."}+ NUpdated>;`
when NUpdated := [{Identifier "."}+] "a1.b2"
};
而且它不起作用。我也尝试过列表,但没有成功。
是否有可能以某种方式创建 {Identifier "."}+
?或者将 list[Identifier]
转换为它?如何在 {Identifier "."}+
上达到 mapper( , toUpperCase)
?
有没有办法将一些 str 变量直接插入到具体语法中?
在文档中我找到了如何将 {Identifier "."}+ 转换为列表。但是有没有其他直接操作{Identifier "."}+.
以一种形式进行模式匹配会很好:
[ *标识符 firstIds, (标识符)<code>someName
, *标识符 otherIds ]
首先是一些简短的回答让事情更清楚:
[NonTerminal] "string"
符号的实现尚未完成。目前它只支持命名非终结符,例如[Identifiers] xxx
。这是一个已知的 TODO 并且它已经作为一个问题被跟踪。
- 目前还没有用于创建具体列表的简短语法。您必须使用循环或递归手动构造它们。目前的建议是:
- 在语法中为列表引入一个非终结符名称,并且
- 编写一个辅助函数来构建列表
要创建一个 {Identifier "."}+
列表,请使用像这样的具体语法模式:
syntax Identifiers = {Identifier "."}+ elems;
private {Identifier "."}+ insert(Identifier first, {Identifier "."}+ tail)
= (Identifiers) `<Identifier first>.<{Identifier "."} tail>`.elems;
append 函数首先将列表包装在 Identifiers
非终结符中以便能够使用 (..)..
符号,然后使用 .elems
投射出新的嵌套列表场地。您像这样生成的语法树是静态正确的。与使用动态调用解析器的 [..]..
表示法不同,此 (..)..
表示法静态调用解析器并在 运行 时组成正确的树。
或者您可能想要连接两个标识符列表:
{Identifier "."}+ append({Identifier "."}+ prefix, {Identifier "."}+ postfix)
= (Identifiers) `<{Identifier "."} prefix>.<{Identifier "."}+ postfix>`.elems;
有时您想连接可能为空的子列表,这是允许的,.
分隔符将自动删除:
{Identifier "."}+ append({Identifier "."}+ prefix, {Identifier "."}* postfix)
= (Identifiers) `<{Identifier "."} prefix>.<{Identifier "."}* postfix>`.elems;
所以要将 list[Identifier]
变成 {Identifier "."}
你可以这样写:
{Identifier "."}+ identifiers([Identifier head]) = (Identifiers) `<Identifier head>`.elems;
{Identifier "."}+ identifiers([Identifier head, Identifier sec, *Identifier tail])
= append(insert(head, identifiers([sec, *tail]);
同意这有点笨拙,我们或许应该优先考虑更简单的具体列表语法模板语法。我们也乐于接受改进建议。
我正在尝试仅使用具体语法(无 AST)重写 java 代码。下一个代码有效:
CompilationUnit rewritePackage(CompilationUnit input) =
visit(input) {
case (PackageDeclaration) `package <{Identifier "."}+ N>;` =>
(PackageDeclaration) `package <{Identifier "."}+ N>.<Identifier s>;`
when s:= [Identifier] "othertest"
};
现在我想创建 {Identifier "."}+
以便将其插入到重写结果中:
CompilationUnit rewritePackage(CompilationUnit input) =
visit(input) {
case (PackageDeclaration) `package <{Identifier "."}+ N>;` =>
(PackageDeclaration) `package <{Identifier "."}+ NUpdated>;`
when NUpdated := [{Identifier "."}+] "a1.b2"
};
而且它不起作用。我也尝试过列表,但没有成功。
是否有可能以某种方式创建
{Identifier "."}+
?或者将list[Identifier]
转换为它?如何在{Identifier "."}+
上达到mapper( , toUpperCase)
?有没有办法将一些 str 变量直接插入到具体语法中?
在文档中我找到了如何将 {Identifier "."}+ 转换为列表。但是有没有其他直接操作{Identifier "."}+. 以一种形式进行模式匹配会很好:
[ *标识符 firstIds, (标识符)<code>someName
, *标识符 otherIds ]
首先是一些简短的回答让事情更清楚:
[NonTerminal] "string"
符号的实现尚未完成。目前它只支持命名非终结符,例如[Identifiers] xxx
。这是一个已知的 TODO 并且它已经作为一个问题被跟踪。- 目前还没有用于创建具体列表的简短语法。您必须使用循环或递归手动构造它们。目前的建议是:
- 在语法中为列表引入一个非终结符名称,并且
- 编写一个辅助函数来构建列表
要创建一个 {Identifier "."}+
列表,请使用像这样的具体语法模式:
syntax Identifiers = {Identifier "."}+ elems;
private {Identifier "."}+ insert(Identifier first, {Identifier "."}+ tail)
= (Identifiers) `<Identifier first>.<{Identifier "."} tail>`.elems;
append 函数首先将列表包装在 Identifiers
非终结符中以便能够使用 (..)..
符号,然后使用 .elems
投射出新的嵌套列表场地。您像这样生成的语法树是静态正确的。与使用动态调用解析器的 [..]..
表示法不同,此 (..)..
表示法静态调用解析器并在 运行 时组成正确的树。
或者您可能想要连接两个标识符列表:
{Identifier "."}+ append({Identifier "."}+ prefix, {Identifier "."}+ postfix)
= (Identifiers) `<{Identifier "."} prefix>.<{Identifier "."}+ postfix>`.elems;
有时您想连接可能为空的子列表,这是允许的,.
分隔符将自动删除:
{Identifier "."}+ append({Identifier "."}+ prefix, {Identifier "."}* postfix)
= (Identifiers) `<{Identifier "."} prefix>.<{Identifier "."}* postfix>`.elems;
所以要将 list[Identifier]
变成 {Identifier "."}
你可以这样写:
{Identifier "."}+ identifiers([Identifier head]) = (Identifiers) `<Identifier head>`.elems;
{Identifier "."}+ identifiers([Identifier head, Identifier sec, *Identifier tail])
= append(insert(head, identifiers([sec, *tail]);
同意这有点笨拙,我们或许应该优先考虑更简单的具体列表语法模板语法。我们也乐于接受改进建议。