Rascal 语法的预测编辑器
Predictive editor for Rascal grammar
我正在尝试为用 Rascal 编写的语法编写一个预测编辑器。其核心是一个函数,它以符号列表作为输入并返回符号类型列表作为输出,这样任何这些类型的实例都将是语法下输入符号的句法合法延续。因此,如果输入列表是 [4,+],则输出可能是 [integer]。在 Rascal 中有没有聪明的方法来做到这一点?我可以想到执行此操作的命令式编程方法,但我怀疑它们没有充分利用 Rascal 的强大功能。
这是个很大的问题。这是一些导致答案的线索,但完整的答案将完全为您实施:-)
- 使用
#
运算符将您感兴趣的语言的原始语法具体化为一个值,以便您可以轻松地查询该语法的简明表示。表示是在扩展 Type
和 Grammar
. 的模块 Type
、ParseTree
上定义的
- 为输入查询构造相同的表示。这可以通过多种方式完成。一种非常棒的语言参数方法是将 Rascal 的解析器算法扩展到 return 部分树以用于部分输入,但我相信现在这会很麻烦。一个更简单的解决方案需要为一组部分输入编写语法,即在特定点具有较短规则的语言语法。语法将是模棱两可的,但在这种情况下不是问题。
- 使用标签标记 "short" 规则,以便您以后可以轻松找到它们:
syntax E = @short E "+";
- 使用扩展的和现在有歧义的语法进行解析;
- 生成的解析树将包含与您用于具体化原始语法的
ParseTree
中相同的表示,只是规则更长,如 prod(E, [E,+,E],...)
- 然后 select 最适合你完成目标的树(使用
@short
标签),并提取它们的产品“prod
”,看起来像这样prod(E,[E,+],...)
。例如,使用 /
运算符:[candidate : /candidate:prod(_,_,/"short") := trees]
,您可以使用光标位置来查找附近的候选对象,而不是那里的所有 short
棵树。
- 使用列表匹配在原始语法中查找前缀,例如
if (/match:prod(_,[*prefix, predicted, *postfix],_) := grammar) ...
,前缀是从 @short
规则中提取的查询。 predicted
是您的答案,postfix
是之后的答案。
- 返回
predicted
符号作为用户阅读的类型:"<type(predicted, ())>"
(即使它是一些复杂的正则表达式类型并正确引用等,也会很好地打印它)
我正在尝试为用 Rascal 编写的语法编写一个预测编辑器。其核心是一个函数,它以符号列表作为输入并返回符号类型列表作为输出,这样任何这些类型的实例都将是语法下输入符号的句法合法延续。因此,如果输入列表是 [4,+],则输出可能是 [integer]。在 Rascal 中有没有聪明的方法来做到这一点?我可以想到执行此操作的命令式编程方法,但我怀疑它们没有充分利用 Rascal 的强大功能。
这是个很大的问题。这是一些导致答案的线索,但完整的答案将完全为您实施:-)
- 使用
#
运算符将您感兴趣的语言的原始语法具体化为一个值,以便您可以轻松地查询该语法的简明表示。表示是在扩展Type
和Grammar
. 的模块 - 为输入查询构造相同的表示。这可以通过多种方式完成。一种非常棒的语言参数方法是将 Rascal 的解析器算法扩展到 return 部分树以用于部分输入,但我相信现在这会很麻烦。一个更简单的解决方案需要为一组部分输入编写语法,即在特定点具有较短规则的语言语法。语法将是模棱两可的,但在这种情况下不是问题。
- 使用标签标记 "short" 规则,以便您以后可以轻松找到它们:
syntax E = @short E "+";
- 使用扩展的和现在有歧义的语法进行解析;
- 生成的解析树将包含与您用于具体化原始语法的
ParseTree
中相同的表示,只是规则更长,如prod(E, [E,+,E],...)
- 然后 select 最适合你完成目标的树(使用
@short
标签),并提取它们的产品“prod
”,看起来像这样prod(E,[E,+],...)
。例如,使用/
运算符:[candidate : /candidate:prod(_,_,/"short") := trees]
,您可以使用光标位置来查找附近的候选对象,而不是那里的所有short
棵树。
- 使用标签标记 "short" 规则,以便您以后可以轻松找到它们:
- 使用列表匹配在原始语法中查找前缀,例如
if (/match:prod(_,[*prefix, predicted, *postfix],_) := grammar) ...
,前缀是从@short
规则中提取的查询。predicted
是您的答案,postfix
是之后的答案。 - 返回
predicted
符号作为用户阅读的类型:"<type(predicted, ())>"
(即使它是一些复杂的正则表达式类型并正确引用等,也会很好地打印它)
Type
、ParseTree
上定义的