Python-Lex-Yacc符号无法访问

问题描述

我正在尝试使用ply,但是我不断遇到这些错误

WARNING: C:\Users\praka\Documents\Kino\Kino-Source-Code\complier.py:84: Rule 'divide' defined,but not used
WARNING: C:\Users\...\complier.py:99: Rule 'vars' defined,but not used
WARNING: C:\Users\...\complier.py:122: Rule 'multiply' defined,but not used
WARNING: C:\Users\...\complier.py:144: Rule 'say' defined,but not used
WARNING: There are 4 unused rules
WARNING: Symbol 'divide' is unreachable
WARNING: Symbol 'vars' is unreachable
WARNING: Symbol 'multiply' is unreachable
WARNING: Symbol 'say' is unreachable

某种程度上,规则是1)定义但未使用的,而2)是不可达的。 我已经尝试了所有我能想到的方法,但是它不起作用! 这是我的代码

from ply import lex,yacc
import rich
import math

ERROR = False
reserved = {
    'say' : "SAY",}

tokens = [
    'MULTIPLY','QUOTE','SPACE','EQUAL','QTEXT','VARIABLES','DIVIDE'
] + list(reserved.values())

Meta = [

]
 
variables = {

}

t_DIVIDE = r"[A-Za-z0-9]+/[A-Za-z0-9]+"
t_MULTIPLY = r"\w_ ?\*\w_ ?"
t_SAY = "say"
t_QUOTE = r"\"" 
t_SPACE = r"\s"
t_QTEXT = r"\".+_ ?\""
t_EQUAL = r"\w+_ ?=\w+_ ?"
t_VARIABLES = r"\w+"

def t_error(t):
    global ERROR
    rich.print(f"[bold red]Illegal character {t.value[0]!r} on line {t.lexer.lineno}[/bold red]")
    t.lexer.skip(1)
    ERROR = True

t_ignore = '\n'

lexer = lex.lex()

def p_divide(t):
    """
    divide : DIVIDE
    """
    try:
        tmp = t[1].split("/")
        for x,i in enumerate(tmp):
            tmp[x] = float(i)
        t.value = tmp[0] / tmp[1]
        print(tmp[0] / tmp[1])
        return t.value
    except ValueError:
        rich.print("[bold red]Multiplying a non number[/bold red]\n[bold blue]Error Ignored,this may cause your program to malfunction,please fix[/bold blue]")


def p_vars_set(t):
    """
    vars : EQUAL
    """
    name = ""
    value = ""
    stripped = str(t[1]).split("=")
    name = stripped[0]
    value = stripped[1]
    variables[name] = value


def p_vars(t):
    """
    vars : VARIABLES
    """
    tmp = t[1]
    for i in t:
        print(i)
    t.value = variables[str(tmp)]
    #return t.value


def p_multiply(t):
    """
    multiply : MULTIPLY
    """
    try:
        tmp = str(t).split("*")
        for i in tmp:
            int(i)
        #t.value = NUM
        return t.value
    except ValueError:
        try:
            if "true" in t:
                print("1")
            if "false" in t:
                print("2")
            else:
                print("0")
        except:
            pass


def p_say_onlyText(t):
    """
    say : SAY QUOTE QTEXT QUOTE
        | SAY SPACE QTEXT 
    """
    l = len(t)
    start = False
    for i in (t):
        if str(i).startswith('"'):
            to_print = str(i).strip('"')
            print(to_print)


def p_error(t):
    global ERROR
    ERROR = True
    if t is None:  # lexer error
        return
    print(f"Syntax Error: {t.value!r}")

parser = yacc.yacc(debug=False,write_tables=False)

if __name__ == "__main__":
    rich.print("[yellow]Hello From The Alter Community[/yellow]")
    try:
       while True:
           i = input(">>")
           parser.parse(i)
    except IndexError:
        rich.print("[bold red]No File Specifed[/bold red]")
        rich.print("[bold blue]Program exited with code 5[/bold blue]")
        exit(5)
    except FileNotFoundError:
        rich.print("[bold red]File Not Found[/bold red]")
        rich.print("[bold blue]Program exited with code 5[/bold blue]")
        exit(5)
    if ERROR == True:
        rich.print("[bold red]Errors![/bold red]")
        rich.print("[bold blue]Program exited with code 1[/bold blue]")
    else:
        rich.print("[bold green]No Errors![/bold green]")
        rich.print("[bold blue]Program exited with code 0[/bold blue]")

不知何故,顶部的bool函数是唯一可以访问的函数,而下面的任何bool函数都不能访问。

解决方法

这些错误通常是由于没有从头开始的结果。

在Ply中,就像在许多解析器生成器中一样,第一个定义的非终结符应该是语法的顶级符号:也就是说,非终结符会派生所有有效输入。

如果出于任何原因您都不希望将顶级符号放在第一位,则可以使用start指定开始符号。有关详细信息,请参见Ply Manual