ply.yacc error: 'ERROR: no rules of the form p_rulename are defined'
ply.yacc error: 'ERROR: no rules of the form p_rulename are defined'
我正在为 c-minus 语言编写解析器。 Lexer 准备就绪并正常工作,所以我开始开发解析器,但我无法从第一部分通过:我收到一个错误,不允许我继续前进,因为我可以看出什么是对的,什么是错的,我只看到下面重现了这个错误。我尝试更改解析器生成器,但仍然无法正常工作。
下面的这段代码是正在运行的词法分析器。它构建了一个识别所有语法符号的词法分析器。
reserved = {
'else' : 'ELSE',
'if' : 'IF',
'int' : 'INT',
'return' : 'RETURN',
'void' : 'VOID',
'while' : 'WHILE'
}
tokens = [
'ID',
'NUM',
'PLUS',
'MINUS',
'MULT',
'DIV',
'LESS',
'LESSOREQUAL',
'GREAT',
'GREATOREQUAL',
'DOUBLEEQUAL',
'NOTEQUAL',
'EQUAL',
'SEMICOLON',
'COLON',
'LPAREN',
'RPAREN',
'LBRACKET',
'RBRACKET',
'LKEY',
'RKEY',
'COMENT'
] + list(reserved.values())
def t_COMENT(t):
r'/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+/'
return t
def t_ID(t):
r'[a-zA-Z]+'
return t
def t_NUM(t):
r'[0-9]+'
return t
def t_PLUS(t):
r'\+'
return t
def t_MINUS(t):
r'\-'
return t
def t_MULT(t):
r'\*'
return t
def t_DIV(t):
r'\/'
return t
def t_LESS(t):
r'\<'
return t
def t_LESSOREQUAL(t):
r'\<\='
return t
def t_GREAT(t):
r'\>'
return t
def t_GREATOREQUAL(t):
r'\>\='
return t
def t_DOUBLEEQUAL(t):
r'\=\='
return t
def t_NOTEQUAL(t):
r'\!\='
return t
def t_EQUAL(t):
r'\='
return t
def t_SEMICOLON(t):
r'\;'
return t
def t_COLON(t):
r'\,'
return t
def t_LPAREN(t):
r'\('
return t
def t_RPAREN(t):
r'\)'
return t
def t_LBRACKET(t):
r'\['
return t
def t_RBRACKET(t):
r'\]'
return t
def t_LKEY(t):
r'\{'
return t
def t_RKEY(t):
r'\}'
return t
def t_newline(t):
r'\n+'
t.lexer.lineno += t.value.count("\n")
def t_error(t):
print("ERROR: Illegal character '{0}' at line {1}".format(t.value[0], t.lineno))
t.lexer.skip(1)
t_ignore = ' \t'
下面这段代码是仍在开发中的解析器。但是我无法测试 none 我正在创建的函数,因为发生了错误。
import ply.yacc as yacc
import lexer
tokens = lexer.tokens
class Parser():
def p_program(p):
'program: declaration_list'
p[0] = p[1]
def p_declaration_list(p):
'''declaration_list: declaration_list declaration
| declaration'''
p[0] = (0, (p[1], 0))
主要:
import ply.yacc as yacc
import ply.lex as lex
from tabulate import tabulate
import sys
from lexer import *
from parser import Parser
lexer = lex.lex()
with open(sys.argv[1], 'r') as f:
lexer.input(f.read())
tok_array = [[tok.type, tok.value, tok.lexpos, tok.lineno] for tok in lexer]
print(tabulate(tok_array, headers=['Tipo','Valor','Posição','Linha']),'\n')
print('passou aqui 1')
parser = yacc.yacc()
with open(sys.argv[1], 'r') as f:
parser.input(f.read())
tok_array = [[tok.type, tok.value, tok.lexpos, tok.lineno] for tok in parser]
print(tabulate(tok_array, headers=['Tipo','Valor','Posição','Linha']),'\n')
下面是完整的错误:
ERROR: no rules of the form p_rulename are defined
Traceback (most recent call last):
File "main.py", line 16, in <module>
parser = yacc.yacc()
File "/home/tlunafar/.local/lib/python3.8/site-packages/ply/yacc.py", line 3323, in yacc
raise YaccError('Unable to build parser')
ply.yacc.YaccError: Unable to build parser
```
Here is the program in c-minus that i am testing:
```
int gcd(int u) {
if (v == 0) return u;
&
else return gcd(v, u-u/v*v);
/* comment */
}
```
Where exactly is this error? Can anybody show me?
如果将解析器定义放入 class 或尝试从不同的模块构建解析器,则需要使用 module=
参数来告诉 yacc
规则是。否则,它找不到它们,您会收到一条错误消息,指出没有找到规则。因此,您需要:
而不是 parser = yacc.yacc()
parser = yacc.yacc(module=Parser)
请注意,所有解析器规则都需要在同一个命名空间中;其中包括 tokens
的定义。所以你需要把它放在 class:
class Parser():
tokens = lexer.tokens
# ...
此外,Ply 坚持要求作品的冒号两边都有空格,因此您必须解决这个问题。还有许多其他错误;值得注意的是,解析器的调用方式与词法分析器不同;他们不是 return 令牌生成器。通常,您只调用一次解析器来解析整个输入。详情在 Ply 手册中。
我正在为 c-minus 语言编写解析器。 Lexer 准备就绪并正常工作,所以我开始开发解析器,但我无法从第一部分通过:我收到一个错误,不允许我继续前进,因为我可以看出什么是对的,什么是错的,我只看到下面重现了这个错误。我尝试更改解析器生成器,但仍然无法正常工作。
下面的这段代码是正在运行的词法分析器。它构建了一个识别所有语法符号的词法分析器。
reserved = {
'else' : 'ELSE',
'if' : 'IF',
'int' : 'INT',
'return' : 'RETURN',
'void' : 'VOID',
'while' : 'WHILE'
}
tokens = [
'ID',
'NUM',
'PLUS',
'MINUS',
'MULT',
'DIV',
'LESS',
'LESSOREQUAL',
'GREAT',
'GREATOREQUAL',
'DOUBLEEQUAL',
'NOTEQUAL',
'EQUAL',
'SEMICOLON',
'COLON',
'LPAREN',
'RPAREN',
'LBRACKET',
'RBRACKET',
'LKEY',
'RKEY',
'COMENT'
] + list(reserved.values())
def t_COMENT(t):
r'/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+/'
return t
def t_ID(t):
r'[a-zA-Z]+'
return t
def t_NUM(t):
r'[0-9]+'
return t
def t_PLUS(t):
r'\+'
return t
def t_MINUS(t):
r'\-'
return t
def t_MULT(t):
r'\*'
return t
def t_DIV(t):
r'\/'
return t
def t_LESS(t):
r'\<'
return t
def t_LESSOREQUAL(t):
r'\<\='
return t
def t_GREAT(t):
r'\>'
return t
def t_GREATOREQUAL(t):
r'\>\='
return t
def t_DOUBLEEQUAL(t):
r'\=\='
return t
def t_NOTEQUAL(t):
r'\!\='
return t
def t_EQUAL(t):
r'\='
return t
def t_SEMICOLON(t):
r'\;'
return t
def t_COLON(t):
r'\,'
return t
def t_LPAREN(t):
r'\('
return t
def t_RPAREN(t):
r'\)'
return t
def t_LBRACKET(t):
r'\['
return t
def t_RBRACKET(t):
r'\]'
return t
def t_LKEY(t):
r'\{'
return t
def t_RKEY(t):
r'\}'
return t
def t_newline(t):
r'\n+'
t.lexer.lineno += t.value.count("\n")
def t_error(t):
print("ERROR: Illegal character '{0}' at line {1}".format(t.value[0], t.lineno))
t.lexer.skip(1)
t_ignore = ' \t'
下面这段代码是仍在开发中的解析器。但是我无法测试 none 我正在创建的函数,因为发生了错误。
import ply.yacc as yacc
import lexer
tokens = lexer.tokens
class Parser():
def p_program(p):
'program: declaration_list'
p[0] = p[1]
def p_declaration_list(p):
'''declaration_list: declaration_list declaration
| declaration'''
p[0] = (0, (p[1], 0))
主要:
import ply.yacc as yacc
import ply.lex as lex
from tabulate import tabulate
import sys
from lexer import *
from parser import Parser
lexer = lex.lex()
with open(sys.argv[1], 'r') as f:
lexer.input(f.read())
tok_array = [[tok.type, tok.value, tok.lexpos, tok.lineno] for tok in lexer]
print(tabulate(tok_array, headers=['Tipo','Valor','Posição','Linha']),'\n')
print('passou aqui 1')
parser = yacc.yacc()
with open(sys.argv[1], 'r') as f:
parser.input(f.read())
tok_array = [[tok.type, tok.value, tok.lexpos, tok.lineno] for tok in parser]
print(tabulate(tok_array, headers=['Tipo','Valor','Posição','Linha']),'\n')
下面是完整的错误:
ERROR: no rules of the form p_rulename are defined
Traceback (most recent call last):
File "main.py", line 16, in <module>
parser = yacc.yacc()
File "/home/tlunafar/.local/lib/python3.8/site-packages/ply/yacc.py", line 3323, in yacc
raise YaccError('Unable to build parser')
ply.yacc.YaccError: Unable to build parser
```
Here is the program in c-minus that i am testing:
```
int gcd(int u) {
if (v == 0) return u;
&
else return gcd(v, u-u/v*v);
/* comment */
}
```
Where exactly is this error? Can anybody show me?
如果将解析器定义放入 class 或尝试从不同的模块构建解析器,则需要使用 module=
参数来告诉 yacc
规则是。否则,它找不到它们,您会收到一条错误消息,指出没有找到规则。因此,您需要:
parser = yacc.yacc()
parser = yacc.yacc(module=Parser)
请注意,所有解析器规则都需要在同一个命名空间中;其中包括 tokens
的定义。所以你需要把它放在 class:
class Parser():
tokens = lexer.tokens
# ...
此外,Ply 坚持要求作品的冒号两边都有空格,因此您必须解决这个问题。还有许多其他错误;值得注意的是,解析器的调用方式与词法分析器不同;他们不是 return 令牌生成器。通常,您只调用一次解析器来解析整个输入。详情在 Ply 手册中。