结合上述词法分析器,还需在词法分析器中加入识别关键字float的部分,设置其单词种别编码为26),构造递归下降分析程序。
时间: 2024-05-15 16:15:11 浏览: 127
语法分析器——递归下降分析法
5星 · 资源好评率100%
以下为词法分析器代码:
```python
import re
# 定义关键字
keywords = {
'if': 1,
'else': 2,
'while': 3,
'do': 4,
'break': 5,
'continue': 6,
'int': 7,
'char': 8,
'void': 9,
'return': 10,
'float': 26
}
# 定义符号
symbols = {
'+': 11,
'-': 12,
'*': 13,
'/': 14,
'=': 15,
'>': 16,
'<': 17,
'>=': 18,
'<=': 19,
'==': 20,
'!=': 21,
';': 22,
'(': 23,
')': 24,
'{': 25,
'}': 26,
',': 27,
':': 28
}
# 定义标识符和常量的正则表达式
id_re = r'[a-zA-Z_]\w*'
int_re = r'\d+'
float_re = r'\d+\.\d+'
# 定义词法分析器函数
def lexer(text):
tokens = []
while text:
# 匹配关键字
for keyword, token in keywords.items():
if text.startswith(keyword):
tokens.append((keyword, token))
text = text[len(keyword):].lstrip()
break
else:
# 匹配符号
for symbol, token in symbols.items():
if text.startswith(symbol):
tokens.append((symbol, token))
text = text[len(symbol):].lstrip()
break
else:
# 匹配标识符
match = re.match(id_re, text)
if match:
tokens.append((match.group(), 29))
text = text[match.end():].lstrip()
else:
# 匹配常量
match = re.match(float_re, text)
if match:
tokens.append((match.group(), 30))
text = text[match.end():].lstrip()
else:
match = re.match(int_re, text)
if match:
tokens.append((match.group(), 31))
text = text[match.end():].lstrip()
else:
# 无法匹配任何模式,抛出异常
raise ValueError('无效的字符: ' + text)
return tokens
```
以下为递归下降分析程序代码:
```python
def parse(tokens):
lookahead = tokens.pop(0)
def factor():
nonlocal lookahead
if lookahead[0] == '(':
match('(')
expr()
match(')')
elif lookahead[1] == 29 or lookahead[1] == 30 or lookahead[1] == 31:
match(lookahead[0])
else:
raise ValueError('语法错误: ' + lookahead[0])
def term():
nonlocal lookahead
factor()
while lookahead[0] in ('*', '/'):
match(lookahead[0])
factor()
def expr():
nonlocal lookahead
term()
while lookahead[0] in ('+', '-'):
match(lookahead[0])
term()
def match(token):
nonlocal lookahead
if lookahead[0] == token:
if tokens:
lookahead = tokens.pop(0)
else:
lookahead = None
else:
raise ValueError('语法错误: ' + lookahead[0])
expr()
```
在该递归下降分析程序中,我们将因子、项和表达式分别定义为函数 `factor`、`term` 和 `expr`,并根据运算符的优先级和结合性来定义它们之间的调用顺序。具体地:
1. 因子可以是括号内的表达式或者标识符、浮点数、整数常量。
2. 项由因子相乘或相除而得。
3. 表达式由项相加或相减而得。
在 `factor` 函数中,我们首先检查当前的词法单元是否是左括号,如果是,则表示它后面有一个表达式,我们需要递归调用 `expr` 函数来解析它;否则,我们检查当前的词法单元是否是标识符或常量,如果是,则表示这是一个因子,我们直接跳过它,否则,抛出语法错误异常。
在 `term` 函数中,我们先解析一个因子,然后检查当前的词法单元是否是乘号或除号,如果是,则表示它后面有一个因子,我们递归调用 `factor` 函数来解析它,否则,表达式已经解析完毕,返回。
在 `expr` 函数中,我们先解析一个项,然后检查当前的词法单元是否是加号或减号,如果是,则表示它后面有一个项,我们递归调用 `term` 函数来解析它,否则,表达式已经解析完毕,返回。
在 `match` 函数中,我们用来检查当前的词法单元是否等于指定的单词,并将当前的词法单元移动到下一个位置。
最后,在 `parse` 函数中,我们首先将输入的词法单元列表中的第一个单词作为当前的词法单元,然后调用 `expr` 函数来解析表达式。
阅读全文