from compyl.lexer import Lexer
rules = [
(r'\s+', None),
(r'\w+', 'ID'),
(r'< *\w+ *>', 'TYPE'), # Will match your <TYPE> token with inner whitespaces
(r'{', 'L_BRACKET'),
(r'}', 'R_BRACKET'),
]
lexer = Lexer(rules=rules, line_rule='\n')
# See ComPyl doc to figure how to proceed from here
Olivier关于词法分析/标记化然后解析的回答很有帮助。在
但是,对于相对简单的情况,一些解析工具能够处理您的需求,而不需要单独的标记化步骤。parsy就是其中之一。您可以从更小的构建块构建解析器-有很好的文档可以帮助您。在
一个用parsy完成的语法分析器的例子如下:http://parsy.readthedocs.io/en/latest/howto/other_examples.html#proto-file-parser。 它比你的复杂得多,但它显示了什么是可能的。如果允许空白(但不是必需的),它使用
lexeme
实用程序(在顶部定义)来使用可选的空白。在您可能需要加强对空白的必要性和可选性的理解,以及空白的真正含义。在
简短回答
所有的问题都归结为这样一个事实:在解析字符串之前,没有对字符串进行标记化。在
冗长的回答
解析过程实际上分为两个不同的部分:词法分析和解析。在
Lexing
在您思考解析的方式中似乎缺少的东西称为标记化或词法分析。它是将字符串转换为令牌流(即单词)的过程。这就是你在问我如何将文本分成不同部分时所要寻找的东西?
您可以通过使用
re
根据regexp列表检查字符串,也可以使用一些著名的库,如PLY。虽然如果您使用的是Python3,我将倾向于使用我编写的词法分析库ComPyl。在所以继续使用ComPyl,您要寻找的语法如下所示。在
注意,第一条规则
(r'\s+', None)
,实际上是解决空白问题的方法。它基本上告诉lexer匹配任何空白字符并忽略它们。当然,如果您不想使用词法分析工具,只需在您自己的re
实现中添加一个类似的规则。在解析
您似乎想编写自己的LL(1)解析器,因此我将简要介绍这一部分。只需知道,有很多工具可以为您做到这一点(PLY和compyllibraries提供了LR(1)解析器,这些解析器功能更强大,但更难手工编写,请看LL(1)和LR(1)here)之间的区别。在
请注意,既然您已经知道如何标记字符串,那么如何查找长度超过1个字符的标记?已解决。现在解析的不是字符流,而是封装匹配的单词的令牌流。在
相关问题 更多 >
编程相关推荐