我怀疑您解析 if 语句的方法不是解决问题的好方法。您还会发现您不能嵌套 IF 语句,也不能将它们全部放在一行中。这就是我将如何去做。
a) 将您的语言转换为 BNF 形式。例如,对于 if 语句,它可能是
ifstmnt ::= IF <condiftion> THEN <trueblock> [ ELSE <elseblock> ]
statment ::= ifstmnt | assignstment | whilestmnt | forstmnt
等
b) 计算出您在每个时间点都在等待什么。在 IF 之后,您读取一个条件,直到您看到 THEN。
c) 编写一个 getNextToken 例程,从您的源中读取字符,直到它有一个完整的令牌。令牌是一个可识别的单元 - IF、THEN、一个数字、一个符号。每次调用它时,它都会将令牌返回到缓冲区中。同时返回一个类型和一个值也很有用——它可以节省您在许多地方转换数字的时间。表驱动方法非常快速和灵活。
d) 然后编写许多小程序来识别每种类型的语句。一个用于IF,一个用于条件,一个用于块,一个用于语句,一个用于表达式等。它们将相互调用并在识别到语句后返回。例如,条件表达式识别器将读取一个布尔表达式并吃掉所有名称、AND、OR 等,直到它向前看并看到 THEN。它无法处理 THEN 因此它存在,并且 IF 识别器发现令牌是 THEN,它读取下一个并调用识别器以获取一个块(可能需要 BEGIN、大量语句然后 END)。
e) 每个例程都收集它需要的数据——条件、真块、假块,并根据需要进行处理。一种非常常见的处理方法是在内存中创建程序的树表示。程序员定义的名称在定义时被收集在字典中,并在使用时进行检查。
f) 然后一个真正的编译器会尝试重新排列树以使事情更有效 - 但我建议这是未来的发展
g) 最后的动作是遍历树,以某种方式评估它。如果您正在编写解释器,则可以计算值并随时存储 - 将值存储在字典中。如果您正在编写真正的编译器,则需要为链接器生成合适的输出。这是一项重大任务。
查看 YACC 和 LEX。它们是为完成部分工作而设计的工具,可以节省您的时间。帮助您研究的术语是“词法分析”“解析器”等。
祝你好运。你的项目很重要!
另见http://nedbatchelder.com/text/python-parsers.html