如何使用 flex/bison 进行类似 python 的缩进
我希望我的语言具有两个功能,使 Python
成为一种格式良好的语言:
- 每行一个语句
- 块以另一个缩进级别开始,一直持续到结束
任何人都可以给我详细的提示,告诉我如何使用类似于 Flex/bison 的工具来实现这一点?这样的块功能迫使用户编写可读的代码。
I want my language to have two features that make Python
such a nicely formatted language:
- One statement per line
- Blocks begin with another indentation level and go on until that's ended
Can anyone give me a detailed hint on how to achieve that with flex/bison
-like tools? Such a block feature forces the user to write readable code.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您可以尝试跟踪词法分析器中的缩进级别,并为缩进和取消缩进添加伪标记。您将需要保留一堆已经看到的缩进级别,并且需要以不同的方式关心空/仅注释行。但我担心最后词法分析器会变得难以维护,并且词法分析器中还有一些特定于解析的状态(缩进堆栈)。
You could try to track the indentation level in the lexer, and add pseudo-tokens for indent and unindent. You will need to keep a stack of already seen indentation levels, and need to care about empty/comment-only lines differently. But I fear that at the end the lexer will become an unmaintainable mess and also you have some parse-specific state (the indentation stack) in your lexer.
Matt Might 写了一篇关于独立解析器的文章,其中介绍了一种使用“unput”处理重要空格的方法:
http://matt.might.net/articles/standalone-lexers-with-lex/
(示例位于页面的中间位置。)
Matt Might wrote an article on standalone parsers, with a way of handling significant whitespace using "unput":
http://matt.might.net/articles/standalone-lexers-with-lex/
(The example is half-way down the page.)
我认为没有办法只用 lex/yacc 来制作一个类似 python 的语法解析器,因为 lex/yacc 只能处理上下文无关语法,但类似 python 的语法是上下文敏感的。
原因是,如果你想查找一条语句和前一条语句是否在同一个块中,你应该让这条语句知道前一条语句的缩进,这就是上下文。
我建议你除了 lex/yacc 之外还做一些额外的逻辑来实现这一点,这不会那么难。您可以在“语法”模块中的此处阅读代码。
关键是,让 lex/yacc 部分解析单个语句,具有缩进级别,并将一些语句打包到块中。
I think there is no way make a python-like syntax parser with ONLY lex/yacc, because lex/yacc can deal with Context Free Grammar only, but a python-like syntax is context sensitive.
The reason is, if you want to find whether a statement and the previous one is in the same block, you should let this statement knows the indentation of the previous one, that's the context.
I suggest you make some additional logic besides lex/yacc to accomplish that, and that won't be so hard. You could read codes here, in "grammar" modules.
The key is, let lex/yacc part parse single statement, with indentation level, and write something packing statements into blocks.