如何用yacc实现一个python的编译器?

yacc for ansi c 的文法在很多地方都可以找到了。为什么没有python的?如何把python源代码中的grammar编译成yacc的?回复内容:
理论上是可以的,关键点在于您要在lexer和parser之间要多加一层,用于分析哪些地方是进入缩进,哪些地方是退出缩进。然后匹配到缩进的时候插入indent和dedent这样的token。至于分析的方法,您可以先建一个stack来存放每一层缩进块的token,然后根据lexer送来的token中的行号、列号等信息来和stack栈顶的数据进行对比,判断下来是该进入缩进的就push一个indent,并这个indent插入到输出的token流中。发现是stack中旧的token匹配的,就把之前的缩进块pop出来,并在输出的token流中插入dedent。然后在paser层面处理语句块的时候可以这样处理(我只写大概意思的伪码,具体您自己看着办)block ::= indent nls statements nls dedentif ::= if lparen expression rparen colon block

1:python这种靠缩进的语言的文法其实是上下文有关的,ebnf是表达不出来的,我不知道yacc是不是有什么丧心病狂的扩展来给你做这个。

2:每一行前面的tab的数量你不要看成一堆tab,要把他的数量本身看成一个整体,也就是说再作语法分析的时候其实是:

[0]def fuck
[1]if true:
[2]fuck
[1]else:
[2]shit
[0]def shit
..

主要是缩进语法的问题吧,只要先在词法上把python的缩进改成类似大括号分界的语法即可,压力在lex这边cpython源码的token分析是用c手撸的,超长,可以看看源码
补充一下 @vczh ,因为是上下文有关的,所以yacc是不行的,不过我通过 peg, ometa 解决什么问题,ometa-js怎么入门/正确理解和认知? 这个问题知道 peg 适合进行。pypeg 这个项目的主页,底下就有对缩进的分析,可以参考一下。
我用c语言实现过一个简化的python解释器,用yacc来分析python的思路如下:1. 在源程序中插入两个虚拟的token:token_begin和token_endtoken_begin标志语法块的开始,token_end标志语法块的结束。看一个例子:

while i < 100: print i i += 1 还不如直接看python源码里的interpreter好了。 cool都日出来了,python算个diao啊,文法拿去,玩吧。写完了我们膜拜一下。https://github.com/python-git/python/blob/master/grammar/grammar

Posted in 未分类

发表评论