在高级的分析器程序中,你可能同时需要多个语法和词法分析器。
依照规则行事不会有问题。不过,你需要小心确定所有东西都正确的绑定(hooked up)了。首先,保证将lex()和yacc()返回的对象保存起来:
~~~
lexer = lex.lex() # Return lexer object
parser = yacc.yacc() # Return parser object
~~~
接着,在解析时,确保给parse()方法一个正确的lexer引用:
~~~
parser.parse(text,lexer=lexer)
~~~
如果遗漏这一步,分析器会使用最新创建的lexer对象,这可能不是你希望的。
词法器和语法器的方法中也可以访问这些对象。在词法器中,标记的lexer属性指代的是当前触发规则的词法器对象:
~~~
def t_NUMBER(t):
r'\d+'
...
print t.lexer # Show lexer object
~~~
在语法器中,lexer和parser属性指代的是对应的词法器对象和语法器对象
~~~
def p_expr_plus(p):
'expr : expr PLUS expr'
...
print p.parser # Show parser object
print p.lexer # Show lexer object
~~~
如果有必要,lexer对象和parser对象都可以附加其他属性。例如,你想要有不同的解析器状态,可以为为parser对象附加更多的属性,并在后面用到它们。
- 0 一些翻译约定
- 1 前言和预备
- 2 介绍
- 3 PLY概要
- 4 Lex
- 4.1 Lex的例子
- 4.2 标记列表
- 4.3 标记的规则
- 4.4 标记的值
- 4.5 丢弃标记
- 4.6 行号和位置信息
- 4.7 忽略字符
- 4.8 字面字符
- 4.9 错误处理
- 4.10 构建和使用lexer
- 4.11 @TOKEN装饰器
- 4.12 优化模式
- 4.13 调试
- 4.14 其他方式定义词法规则
- 4.15 额外状态维护
- 4.16 Lexer克隆
- 4.17 Lexer的内部状态
- 4.18 基于条件的扫描和启动条件
- 4.19 其他问题
- 5 语法分析基础
- 6 Yacc
- 6.1 一个例子
- 6.2 将语法规则合并
- 6.3 字面字符
- 6.4 空产生式
- 6.5 改变起始符号
- 6.6 处理二义文法
- 6.7 parser.out调试文件
- 6.8 处理语法错误
- 6.9 行号和位置的跟踪
- 6.10 构造抽象语法树
- 6.11 嵌入式动作
- 6.12 Yacc的其他
- 7 多个语法和词法分析器
- 8 使用Python的优化模式
- 9 高级调试
- 9.1 调试lex()和yacc()命令
- 9.2 运行时调试
- 10 如何继续