我是ANTLR4的新手,我正在尝试使用ANTLR解析Python中的分数表达式,然后将它们更改为Python可以理解的结构。使用ANTLR而不是regex的主要原因是嵌套模式的递归。
在我的例子中,分数的结构是\\frac{a}{b}
,我想要的格式是(a/b)
。已经有类似的项目做过,比如latex2symy,但我正在努力理解它是如何工作的。
解析器可以在python中找到匹配项。例如,对于\frac{1}{2}
,它返回(result_ (expr (fraction \frac { 1 } { 2 })))
。结果来自一个“树”,我可以提取它的一部分,如数字(1和2),然后用(1/2)
的形式替换它们吗?
下面是我生成的语法文件:
grammar frac_gram;
options{
language=Python3;
}
/*
* Parser Rules
*/
result_ : expr+ ;
expr : fraction;
integer : INT;
fraction: FRAC L_BRACE integer R_BRACE L_BRACE integer R_BRACE;
/*
* Lexer Rules
*/
FRAC: '\\frac';
L_BRACE: '{';
R_BRACE: '}';
INT : [0-9]+ ; // match integers
WS : [ \t]+ -> skip ; // toss out whitespace
Python代码:
import sys
from antlr4 import *
from antlr4.InputStream import InputStream
from frac_gram_grammarLexer import frac_gram_grammarLexer
from frac_gram_grammarParser import frac_gram_grammarParser
from frac_gram_grammarVisitor import frac_gram_grammarVisitor
def main(argv):
input_stream = InputStream(argv)
lexer = frac_gram_grammarLexer(input_stream)
token_stream = CommonTokenStream(lexer)
parser = frac_gram_grammarParser(token_stream)
tree = parser.result_()
lisp_tree_str = tree.toStringTree(recog=parser)
print(lisp_tree_str)
visitor = frac_gram_grammarVisitor()
visitor.visit(tree)
if __name__ == '__main__':
main('\\frac{1}{2}')
1条答案
按热度按时间vm0i2vca1#
经过大量的搜索,我发现解决办法是命名语法文件中的分子和分母部分,即。
因此,我将分子命名为upper,将分母命名为lower,然后在ANTLR解析器根据其属性对其进行解析后,可以在Python中提取它