PLY 不匹配正确的终端
PLY not matching the correct terminal
我在 PLY 中创建了一个简单的解析器,它有两个规则:
- 当
:
先出现时,出现一个名字
- 当
=
先出现时,会出现一个数字
对应代码:
from ply import lex, yacc
tokens = ['Name', 'Number']
def t_Number(t):
r'[0-9]'
return t
def t_Name(t):
r'[a-zA-Z0-9]'
return t
literals = [':', '=']
def t_error(t):
print("lex error: " + str(t.value[0]))
t.lexer.skip(1)
lex.lex()
def p_name(p):
'''
expression : ':' Name
'''
print("name: " + str(list(p)))
def p_number(p):
'''
expression : '=' Number
'''
print("number: " + str(list(p)))
def p_error(p):
print("yacc error: " + str(p.value))
yacc.yacc()
yacc.parse("=3")
yacc.parse(":a")
yacc.parse(":3")
我的期望是,如果它看到 :
或 =
它会进入相应的规则并尝试匹配相应的终端。然而在第三个例子中,它匹配了一个应该是名字的数字然后失败了。
Afaik 语法应该是上下文无关的(需要解析),是这样吗?另外,当一个标记是另一个标记的超集时,我将如何处理?
Ply 在查询语法之前进行标记化,因此上下文不会影响标记化。(更准确地说,解析器接收由词法分析器生成的标记流。这两个过程在实践中交错,但它们保持独立。)
您可以将上下文构建到词法分析器中,但这会很快变得丑陋。 (尽管如此,这是一种常见的策略。)
最好的办法是编写词法规则以尽可能生成最细粒度的结果,然后编写语法以接受所有备选方案:
def p_name(p):
'''
expression : ':' Name
expression : ':' Number
'''
print("name: " + str(list(p)))
def p_number(p):
'''
expression : '=' Number
'''
print("number: " + str(list(p)))
假设您更改了词法规则以将最具体的模式放在首位。
我在 PLY 中创建了一个简单的解析器,它有两个规则:
- 当
:
先出现时,出现一个名字 - 当
=
先出现时,会出现一个数字
对应代码:
from ply import lex, yacc
tokens = ['Name', 'Number']
def t_Number(t):
r'[0-9]'
return t
def t_Name(t):
r'[a-zA-Z0-9]'
return t
literals = [':', '=']
def t_error(t):
print("lex error: " + str(t.value[0]))
t.lexer.skip(1)
lex.lex()
def p_name(p):
'''
expression : ':' Name
'''
print("name: " + str(list(p)))
def p_number(p):
'''
expression : '=' Number
'''
print("number: " + str(list(p)))
def p_error(p):
print("yacc error: " + str(p.value))
yacc.yacc()
yacc.parse("=3")
yacc.parse(":a")
yacc.parse(":3")
我的期望是,如果它看到 :
或 =
它会进入相应的规则并尝试匹配相应的终端。然而在第三个例子中,它匹配了一个应该是名字的数字然后失败了。
Afaik 语法应该是上下文无关的(需要解析),是这样吗?另外,当一个标记是另一个标记的超集时,我将如何处理?
Ply 在查询语法之前进行标记化,因此上下文不会影响标记化。(更准确地说,解析器接收由词法分析器生成的标记流。这两个过程在实践中交错,但它们保持独立。)
您可以将上下文构建到词法分析器中,但这会很快变得丑陋。 (尽管如此,这是一种常见的策略。)
最好的办法是编写词法规则以尽可能生成最细粒度的结果,然后编写语法以接受所有备选方案:
def p_name(p):
'''
expression : ':' Name
expression : ':' Number
'''
print("name: " + str(list(p)))
def p_number(p):
'''
expression : '=' Number
'''
print("number: " + str(list(p)))
假设您更改了词法规则以将最具体的模式放在首位。