TEST语言编译器 目录
语法分析
语法分析程序的功能是:对词法分析的结果,根据语法规则,将一个个单词符号组成语言的各种语言类。分析时发现有不合语法规则的符号,要将错误符号和性质报告给程序员(错误检测)。
TEST语言语法规则
详细规则参照原书附录 A.2
规则变动:
大部分语法规则和C语言相似,其中write语句定义为向变量输入值,read语句定义为读取表达式的值。
for语句正则文法改为< for_statement > -> for’(’< expression >;< expression >;< expression >’)’< statement >
添加语法:(更接近于C语言)
do while语句:< dowhile_statement > -> do < statement > while’(’< expression >’)’
switch语句:< switch_statement > - > switch’(’< expression >’)’ ‘{’ {case < expression >:< statement_list >} ‘}’
break语句:< break_statement > -> break;
continue语句:< continue_staement > -> continue;
语法分析程序设计
笔者通过分析word.josn文件(词法分析结果文件)的每个单词,严格依据语法规则,生成类似语法树的数据结构存储在parses.josn文件中。分系同时进行错误检测,抛出不符合语法规则的异常。
parse_analysis.py
import json
from myexception import MyException, error_path@error_path
def parse_analysis():# 读取词法分析文件words.jsonwith open('words.json', 'r') as f:words = json.load(f)# 词索引号global indexindex = 0# <program> -> '{' <declaration_list> <statement_list> '}'@error_pathdef program():global indexif not words[index].get('type') == '{':raise MyException('程序缺失左括号!')index += 1dl = declaration_list()sl = statement_list()if not words[index].get('type') == '}':raise MyException('程序缺失右括号!')index += 1return {
'type': 'program', 'declaration_list': dl, 'statement_list': sl}# <declaration_list> -> {<declaration>}@error_pathdef declaration_list():global indexdeclarations = []while words[index].get('type') == 'int':d = declaration()declarations.append(d)index += 1return {
'type': 'declaration_list', 'declarations': declarations}# <declaration> -> int ID;@error_pathdef declaration():global indexindex += 1if words[index].get('type') == 'ID':index += 1if words[index].get('type') == ';':return {
'type': 'declaration', 'variable': words[index - 1].get('val')}else:raise MyException('缺失分号!')else:raise MyException('变量声明出错!')# <statement_list> -> {<statement>}@error_pathdef statement_list():global indexstatements = []while words[index].get('type') != '}' and words[index].get('type') != 'case':s = statement()statements.append(s)return {
'type': 'statement_list', 'statements': statements}# <statement> -> <if_statement> | <while_statement> | <for_statement> | <read_statement> |# <write_statement> | <expression_state> | <compound_statement> | <dowhile_statement> |# <switch_statement> | <break_statement> | <continue_statement>@error_pathdef statement():global indexstatement_start = {
'if': if_statement, 'while': while_statement, 'for': for_statement,'read': read_statement, 'write': write_statement, 'expr': expression_statement,'{': compound_statement