我正在尝试解析 Presentation MathML 并使用 ANTLR 构建 AST。我支持大多数标签,并且可以为特定构造构建节点。
我遇到了运营商的麻烦。在本页面;
http://www.w3.org/TR/MathML3/appendixc.html
有一个运算符列表,它们默认出现的形式(前缀、中缀或后缀)和一个优先级值,它给出了运算符的优先级。
我可以将每个运算符代码添加到我的词法分析器中,然后根据优先级为一元、二元和后缀表达式编写规则,就像我为 C 或其他编程语言编写表达式一样。
问题是操作符标签可以包含一个“form”属性,该属性可以取值“prefix”、“infix”和“postfix”,这会改变树结构。我在解析器阶段之前看不到属性。
此外,运算符标签可以包含充当运算符的自然语言,因此我无法推断优先级并因此构建正确的树。
是否可以在解析器阶段忽略运算符优先级,只需将表达式作为节点列表加载,然后在语义阶段使用树遍历器重新编写树?在这个阶段我将拥有属性值,并且我拥有一个已知运算符及其优先级/优先级的字典。
这是我进步的一个重要里程碑,因为我必须在继续之前决定我能做什么。
编辑
我有以下 MathML 表达式...
<math>
<mrow>
<mi>a</mi>
<mo>+</mo>
<mi>b</mi>
<mo>+</mo>
<mi>c</mi>
</mrow>
</math>
我可以建造两棵不同的树...
或者...
第二个编码树中“+”运算符的关联性,这就是我们通常对编程语言所做的。
但是规范中有数百个运算符,所以我的语法会非常大,并且我的生产规则中有很多替代方案。
自然语言也可以用于操作员(虽然真的不应该)......
<math>
<mrow>
<mo>there exists</mo>
<mi>x</mi>
<mo>in</mo>
<mi>S</mi>
</mrow>
</math>
所以我要问的是对树中的运算符进行编码的最佳方法是什么。我正在尝试将演示文稿 MathML 转换为 Content MathML,因此我需要分析演示文稿的语义以便能够确定它在数学上的含义。
有没有办法在树语法阶段将第一棵树转换为第二棵树?
编辑
我有以下 MathML 和生成的树...
<math>
<mrow>
<mi>a</mi>
<mo>+</mo>
<mi>b</mi>
<mo>+</mo>
<mi>c</mi>
</mrow>
</math>
这是一个简单的树语法,我想用它来查找其他MO
节点之间的任何节点,例如MI
...
tree grammar SimpleReWriter;
options
{
tokenVocab = MathML;
ASTLabelType = CommonTree;
output = AST;
backtrack = true;
language = CSharp3;
filter = true; // use pattern matching
rewrite = true;
}
topdown: findInfix; // look for infix operators
findInfix : ^(MROW left=.+ MO right=.+) -> ^(MROW ^(MO $left $right));
我的程序在课堂内崩溃SimpleReWriter
,并显示错误消息:Operation is not valid due to the current state of the object.
如果节点之间只有一个,我的树语法就可以工作+
,但是当有一个以上的序列时,它就会崩溃。