用AI赚第一桶💰低成本搭建一套AI赚钱工具,源码可二开。 广告
位置跟踪通常是个设计编译器时的技巧性玩意儿。默认情况下,PLY跟踪所有标记的行号和位置,这些信息可以这样得到: * p.lineno(num)返回第num个符号的行号 * p.lexpos(num)返回第num个符号的词法位置偏移 例如: ~~~ def p_expression(p): 'expression : expression PLUS expression' p.lineno(1) # Line number of the left expression p.lineno(2) # line number of the PLUS operator p.lineno(3) # line number of the right expression ... start,end = p.linespan(3) # Start,end lines of the right expression starti,endi = p.lexspan(3) # Start,end positions of right expression ~~~ 注意:lexspan()方法只会返回的结束位置是最后一个符号的起始位置。 虽然,PLY对所有符号的行号和位置的跟踪很管用,但经常是不必要的。例如,你仅仅是在错误信息中使用行号,你通常可以仅仅使用关键标记的信息,比如: ~~~ def p_bad_func(p): 'funccall : fname LPAREN error RPAREN' # Line number reported from LPAREN token print "Bad function call at line", p.lineno(2) ~~~ 类似的,为了改善性能,你可以有选择性的将行号信息在必要的时候进行传递,这是通过p.set_lineno()实现的,例如: ~~~ def p_fname(p): 'fname : ID' p[0] = p[1] p.set_lineno(0,p.lineno(1)) ~~~ 对于已经完成分析的规则,PLY不会保留行号信息,如果你是在构建抽象语法树而且需要行号,你应该确保行号保留在树上。