是否可以将从文本文件中检索到的终端附加到Rascal的词典中?这将在运行时发生,我认为没有明显的方法来实现这一点。我宁愿将数据与Rascal项目分开。例如,如果我从文本文件中读取了国家/地区列表,我将如何将其添加到词典中(使用lexical
关键字)?
答案 0 :(得分:1)
在Rascal解析器的数据相关版本中,这更容易,更快,但我们还没有发布它。现在我要编写一个带有解析后过滤器的通用规则,如下所示:
rascal>set[str] lexicon = {"aap", "noot", "mies"};
set[str]: {"noot","mies","aap"}
rascal>lexical Word = [a-z]+;
ok
rascal>syntax LexiconWord = word: Word w;
ok
rascal>LexiconWord word(Word w) { // called when the LexiconWord.word rule is use to build a tree
>>>>>>> if ("<w>" notin lexicon)
>>>>>>> filter; // remove this parse tree
>>>>>>> else fail; // just build the tree
>>>>>>>}
rascal>[Sentence] "hello"
|prompt:///|(0,18,<1,0>,<1,18>): ParseError(|prompt:///|(0,18,<1,0>,<1,18>))
at $root$(|prompt:///|(0,64,<1,0>,<1,64>))
rascal>[Sentence] "aap"
Sentence: (Sentence) `aap`
rascal>
因为filter
函数删除了hello
的所有可能派生,解析器最终会在hello
上返回解析错误。对于词典中的aap
,它没有这样做,所以欢呼。当然,您可以使用这种过滤进行有趣的复杂派生。人们有时会写出含糊不清的语法并使用类似的过滤器来使其明确无误。
如果过滤函数处于摊销的恒定时间,则以这种方式的解析和过滤就输入的长度而言是在最坏情况下的时间。如果语法是线性的,那么当然整个过程也是线性的。
答案 1 :(得分:0)
完全不同的答案是动态更新语法并从中生成解析器。这涉及到反对Rascal的内部语法表示,如下所示:
set[str] lexicon = {"aap", "noot", "mies"};
syntax Word = ; // empty definition
typ = #Word;
grammar = typ.definitions;
grammar[sort("Word")] = { prod(sort("Word"), lit(x), {}) | x <- lexicon };
newTyp = type(sort("Word"), grammar);
这个newType是一个用于词典定义的具体语法+类型,现在可以这样使用:
import ParseTree;
if (type[Word] staticGrammar := newType) {
parse(staticGrammar, "aap");
}
现在写了这两件事: