语法分析
语法分析程序的功能是:对词法分析的结果,根据语法规则,将一个个单词符号组成语言的各种语言类。分析时发现有不合语法规则的符号,要将错误符号和性质报告给程序员(错误检测)。
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.json
with open('words.json', 'r') as f:
words = json.load(f)
# 词索引号
global index
index = 0
# <program> -> '{' <declaration_list> <statement_list> '}'
@error_path
def program():
global index
if not words[index].get('type') == '{':
raise MyException('程序缺失左括号!')
index += 1
dl = declaration_list()
sl = statement_list()
if not words[index].get('type') == '}':
raise MyException('程序缺失右括号!')
index += 1
return {
'type': 'program', 'declaration_list': dl, 'statement_list': sl}
# <declaration_list> -> {<declaration>}
@error_path
def declaration_list():
global index
declarations = []
while words[index].get('type') == 'int':
d = declaration()
declarations.append(d)
index += 1
return {
'type': 'declaration_list', 'declarations': declarations}
# <declaration> -> int ID;
@error_path
def declaration():
global index
index += 1
if words[index].get('type') == 'ID':
index += 1
if words[index].get('type') == ';':
return {
'type': 'declaration', 'variable': words[index - 1].get('val')}
else:
raise MyException('缺失分号!')
else:
raise MyException('变量声明出错!')
# <statement_list> -> {<statement>}
@error_path
def statement_list():
global index
statements = []
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_path
def statement():
global index
statement_start = {
'if': if_statement, 'while': while_statement, 'for': for_statement,
'read': read_statement, 'write': write_statement, 'expr': expression_statement,
'{': compound_statement