2

(抱歉,不确定 ad-hoc 是否是正确的词……欢迎提出更好的建议)

我正在尝试在 Java 应用程序中解析 Galaxy ToolConfig XML CLI 工具包装格式,以便(部分)复制 Galaxy 软件本身的行为。

该格式在命令标签内包含一些“自由文本” if/else 子句(这是它们出现的唯一位置,AFAIK):

...
<command interpreter="python">
  sam_to_bam.py
    --input1=$source.input1
    --dbkey=${input1.metadata.dbkey} 
    #if $source.index_source == "history":
      --ref_file=$source.ref_file
    #else
      --ref_file="None"
    #end if
    --output1=$output1
    --index_dir=${GALAXY_DATA_INDEX_DIR}
</command>
...

将这种 if/else 结构解析为可用于在 Java 中重塑 if/else 逻辑的推荐策略是什么?

BNF/ANTLR 是不是过大了,最好只是解析成一些对象结构,还是?任何适合这里的设计模式?(以前没有与 BNF/ANTLR 合作过,但如果值得的话,我愿意研究它)。

4

1 回答 1

2

如果要捕获输入的所有结构,解析器是唯一的方法。可以手动自顶向下递归编写解析器,但这样做没有什么意义,这就是存在解析器生成器工具的原因;使用它们。

关于#if #then #else:如果这是您要捕获的唯一结构,那么您只需要一个非常原始的语法,该语法还允许包含任意文本的标记将 #if#then#else 结构之间的粘性物作为一团文本。

如果您想捕获所有代码结构,并且仅在某些地方允许使用条件,那么它们的存在可以简单地集成到您正在使用的任何 BNF 中。

如果,正如我所怀疑的,这些可以发生在任何地方(“临时”?#if 遵循 C 预处理器样式,并且这些条件几乎可以出现在输入流中的任何地方),那么解析文本保留条件目前正在流血最先进的解析可以做什么的边缘。这是标准的 C 预处理疾病,对此没有好的解决方案。在这种情况下,标准解析器生成器几乎无济于事。(手工编码的解析器在这里也没有更好的表现;在任何一种情况下都必须使用相同的解决方案)。

处理此问题的最新方案之一(仅在过去几个月中作为博士研究结果报告)是在发现#if 标记来处理#if 和#else 时分叉解析,并在找到#endif 时加入;那么你需要一种方法来融合生成的子树,通常作为标记有条件的哪个分支的模棱两可的子树。

如果你想继续你的生活,我建议你坚持这些条件出现在语法中明确定义的位置,并忍受编写非结构化预处理器指令的人偶尔抱怨。(“你写了疯狂的代码?抱歉,我的工具无法处理它”)。

于 2011-07-22T14:29:24.620 回答