为了处理大量的编译时间和语法的重用,我将语法组成了几个按顺序调用的子语法。其中之一(称为:SETUP 语法)提供了解析器的一些配置(通过符号解析器),因此后面的子语法在逻辑上依赖于该语法(再次通过不同的符号解析器)。因此,在解析SETUP之后,需要更改以下子语法的符号解析器。
我的问题是,如何有效地解决这个问题,同时保持子语法之间的松散耦合?
目前我只看到两种可能性:
- SETUP 语法的 on_success 处理程序可以完成这项工作,但这会引入相当多的耦合。
- 设置完成后,将所有内容解析为字符串,构建一个新的解析器(根据更改后的符号)并在第二步中解析该字符串。这会留下相当多的开销。
我想要的是一个 on_before_parse 处理程序,它可以由任何需要在每次解析之前做一些工作的语法来实现。从我的角度来看,这会减少耦合,并且解析器的某些设置在其他情况下也可以派上用场。这样的事情可能吗?
Update:
抱歉,我太粗略了,这不是我的本意。
任务是使用一些关键字解析输入 I,例如#task1
and #task2
。但在某些情况下,这些关键字需要不同,例如$$task1
and $$task2
.
所以解析的文件将以
setup {
#task1=$$task1
#task2=$$task2
}
realwork {
...
}
一些代码草图:给定是一个主解析器,由几个(至少两个)解析器组成。
template<typename Iterator>
struct MainParser: qi::grammar<Iterator, Skipper<Iterator>> {
MainParser() : MainParser::base_type(start) {
start = setup >> realwork;
}
Setup<Iterator> setup;
RealWork<Iterator> realwork;
qi::rule<Iterator, Skipper<Iterator> > start;
}
Setup
and RealWork
它们本身就是解析器(我上面的子解析器)。在设置部分期间,语法的某些关键字可能会改变,因此设置部分有一个qi::symbols<char, keywords>
规则。一开始这些符号将包含#task1
and #task2
。解析文件的第一部分后,它们包含$$task1
and $$task2
.
由于关键字已更改,并且自RealWork
需要解析 I,它需要了解新的关键字。所以我必须从Setup
to RealWork
在文件配对期间。
我看到的两种方法是:
- 使
Setup
意识到RealWork
并传输符号Setup
to RealWork
in the qi::on_success
的处理程序Setup
。 (坏,耦合)
-
切换到两个解析步骤。start
of MainParser
看起来像
start = setup >> unparsed_rest
之后会有第二个解析器MainParser
。示意图:
SymbolTable Table;
string Unparsed_Rest;
MainParser.parse(Input, (Unparsed_Rest, Table));
RealWordParser.setupFromAlteredSymbolTable(Table);
RealWorkParser.parse(Unparsed_Rest);
几个解析步骤的开销。
所以,到目前为止,属性还没有发挥作用。只需在解析时更改解析器即可处理多种输入文件。
我的希望是一个处理者qi::on_before_parse
like qi::on_success
。从这个想法来看,每次解析器开始解析输入时都会触发该处理程序。理论上只是在解析开始时的拦截,就像我们有拦截一样on_success
and on_error
.