lexical-analysis - 在 Rascal 中处理复杂的词汇

标签 lexical-analysis rascal

在 Rascal 中处理复杂文字的最佳实践是什么?

来自 JavaScript 的两个示例(我的 DSL 有类似的情况):

  • 带有 \ 转义的字符串 - 必须转义为实际值。
  • 正则表达式文字 - 需要自己的子 AST。

implode 拒绝将词汇映射到抽象树,它们显然是 handed differently尽管有完整的解析树可用,但来自语法产生式。例如,以下解析器失败并显示 IllegalArgument("Missing lexical constructor"):

module lexicals

import Prelude;

lexical Char = "\\" ![] | ![\\]; // potentially escaped character
lexical String = "\"" Char* "\""; // if I make this "syntax", implode works as expected

start syntax Expr = string: String;

data EXPR = string(list[str] chars);

void main(list[str] args) {
    str text = "\"Hello\\nworld\"";
    print(implode(#EXPR, parse(#Expr, text)));
}

到目前为止,我唯一的想法是将所有词汇捕获为原始字符串,然后使用单独定义的语法(没有布局空格)重新解析它们(内爆和全部)。希望有更好的方法。

最佳答案

implode 将解析树转换为 ast 的方式是 rascal tutor:implode 中的文档。 。其中包含以下规则:

Unlabeled lexicals are imploded to str, int, real, bool depending on the expected type in the ADT. To implode lexical into types other than str, the PDB parse functions for integers and doubles are used. Boolean lexicals should match "true" or "false". NB: lexicals are imploded this way, even if they are ambiguous.

因此,解决方案 1 是为您的作品添加标签:

lexical String = string: "\"" Char* "\"";

此外,也许您不需要在解析树旁边放置 AST?至少不需要与你的语法紧密匹配。两种常见的情况是:

  1. 您需要 AST,因为语法结构不适合您的目的。在这种情况下,您必须手动编写 implode 函数。
  2. 你的解析树的结构已经足够好了。在这种情况下,请查看 Concrete Syntax 的示例。这是一种非常干净的方式来处理 rascal 中嵌套的目标语言。

我们越来越倾向于弃用 implode 函数,因为我们的具体语法对于大多数情况来说足够强大。

关于lexical-analysis - 在 Rascal 中处理复杂的词汇,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30490384/

相关文章:

caching - 如何在 Rascal MPL 中序列化/反序列化数据到文件

rascal - 我的变量有注释吗?

c - 在 Lex 的输入文件中插入文本(使用 C)

regex - Rascal 中正则表达式匹配的大小有限制吗?

rascal - 在 Rascal 中返回相同字符串的框回调函数

c - BNF 到 Lex 到 C 语言的解析器

rascal - 获取字符串形式的类和方法的名称

python - 如何编写Python词法分析器?

f# - 如何在 F# 中使用返回不同类型的函数?

elasticsearch - Stempel Polish Analysis插件作为Elasticsearch的插件不起作用