I'm trying to work with ply, but I keep getting these errors:
WARNING: C:\Users\...\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
Somehow the rules are 1) defined but not used, and 2) are unreachable. I've tried everything I can think of, but it won't work! Here is my code:
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]")
Somehow, the bool function at the top is the only function that is reachable, and any function below that is not.
These errors are usually the result of not starting at the beginning.
In Ply, as in many parser generators, the first defined non-terminal is expected to be the grammar's top-level symbol: that is, the non-terminal which derives all valid inputs.
If for whatever reason you don't want to put the top-level symbol first, you can specify the start symbol with start
. See the Ply Manual for details.