📜  打印由给定语法下的表达式表示的单词的排序列表(1)

📅  最后修改于: 2023-12-03 15:10:02.393000             🧑  作者: Mango

打印由给定语法下的表达式表示的单词的排序列表

本文介绍了一个程序,它能够根据给定的语法,打印出表达式中使用的单词的排序列表。下面将逐步介绍该程序的设计思路。

设计思路
  1. 定义语法规则

首先,我们需要定义使用的语法规则。在本例中,我们将使用以下语法规则:

<expression> ::= <term> '+' <expression> | <term> '-' <expression> | <term>
<term> ::= <factor> '*' <term> | <factor> '/' <term> | <factor>
<factor> ::= '(' <expression> ')' | <number> | <variable>
<number> ::= <digit> | <digit> <number>
<variable> ::= <letter> | <letter> <variable>
<digit> ::= '0' | '1' | ... | '9'
<letter> ::= 'a' | 'b' | ... | 'z' | 'A' | 'B' | ... | 'Z'

上面的规则定义了表达式中可能用到的符号和变量类型。我们需要对表达式进行解析,并按照定义的语法规则进行分类。

  1. 解析表达式

我们将使用递归下降分析来解析表达式。

下面是一个简化的解析器实现:

def expression():
    term()
    t = peek()
    while t == '+' or t == '-':
        get_token()
        term()
        t = peek()

def term():
    factor()
    t = peek()
    while t == '*' or t == '/':
        get_token()
        factor()
        t = peek()

def factor():
    t = peek()
    if t == '(':
        get_token()
        expression()
        if peek() == ')':
            get_token()
    elif t == 'number' or t == 'variable':
        get_token()
    else:
        raise SyntaxError("Unexpected token: {}".format(t))

在这个示例中,我们定义了三个函数:expressiontermfactor。这三个函数按照语法规则进行解析,并相互调用以构建表达式。

  1. 生成单词列表

我们需要在解析表达式的同时,将表达式中使用的单词添加到列表中。我们可以在 get_token 函数中完成这个任务:

def get_token():
    global current_token
    if current_token is None:
        current_token = next_token()
    if current_token['type'] == 'operator' or current_token['type'] == 'control':
        raise SyntaxError("Unexpected token: {}".format(current_token))
    tokens.append(current_token)
    current_token = None

在这个示例中,我们检查当前的单词类型是否为运算符或控制字符,如果是则抛出“意外的单词”异常。否则,我们将单词添加到 tokens 列表中。

  1. 对单词进行排序并打印

我们可以使用 Python 的 sorted 函数来对单词列表进行排序,并将排序后的结果打印出来:

tokens = []

# parsing functions ...

def main():
    expression()
    for token in sorted(set(tokens)):
        print(token)

在这个示例中,我们首先调用 expression 函数,解析表达式并存储单词列表。然后,我们对单词列表进行去重和排序,并遍历打印每个单词。

代码实现

下面是一个完整的程序的代码实现:

import re

def tokenize(expression):
    tokens = []
    for match in re.findall(r"(\d+|[a-zA-Z]+|\S)", expression):
        if match.isdigit():
            tokens.append({'type': 'number', 'value': match})
        elif match in ['+', '-', '*', '/', '(', ')']:
            tokens.append({'type': 'operator', 'value': match})
        elif match in [' ', '\t']:
            continue
        else:
            tokens.append({'type': 'variable', 'value': match})
            
    return tokens

def peek():
    if current_token is None:
        current_token = next_token()
    return current_token['type']

def get_token():
    global current_token
    if current_token is None:
        current_token = next_token()
    if current_token['type'] == 'operator' or current_token['type'] == 'control':
        raise SyntaxError("Unexpected token: {}".format(current_token))
    tokens.append(current_token)
    current_token = None

def expression():
    term()
    t = peek()
    while t == '+' or t == '-':
        get_token()
        term()
        t = peek()

def term():
    factor()
    t = peek()
    while t == '*' or t == '/':
        get_token()
        factor()
        t = peek()

def factor():
    t = peek()
    if t == '(':
        get_token()
        expression()
        if peek() == ')':
            get_token()
    elif t == 'number' or t == 'variable':
        get_token()
    else:
        raise SyntaxError("Unexpected token: {}".format(t))


if __name__ == '__main__':
    current_token = None
    expression_str = 'a + b * c - 8'
    tokens = tokenize(expression_str)
    main()
结论

本文介绍了一个解析表达式并生成单词列表的程序。该程序可以根据定义的语法规则,将表达式中使用的单词进行分类,并按照字母顺序进行排序。该程序可以通过调整语法规则以适应其他类型的表达式。