Python 获取不符合';没有意义:`语法错误在';('`

Python 获取不符合';没有意义:`语法错误在';('`,python,yacc,lexer,ply,patsy,Python,Yacc,Lexer,Ply,Patsy,我正在编写一个字符串解析器来执行类似于 我已经让操作符工作(:,+,-,/,等等),但我似乎无法让函数工作。我只是复制粘贴直接相关的函数 from ply import yacc, lex em_data = {'a': ['a1', 'a1', 'a2', 'a2', 'a1', 'a1', 'a2', 'a2'], 'b': ['b1', 'b2', 'b1', 'b2', 'b1', 'b2', 'b1', 'b2'], 'x1': [1.7

我正在编写一个字符串解析器来执行类似于

我已经让操作符工作(:,+,-,/,等等),但我似乎无法让函数工作。我只是复制粘贴直接相关的函数

from ply import yacc, lex


em_data = {'a': ['a1', 'a1', 'a2', 'a2', 'a1', 'a1', 'a2', 'a2'],
           'b': ['b1', 'b2', 'b1', 'b2', 'b1', 'b2', 'b1', 'b2'],
           'x1': [1.76405235, 0.40015721, 0.97873798, 2.2408932, 1.86755799,
                                   -0.97727788, 0.95008842, -0.15135721],
           'x2': [-0.10321885, 0.4105985, 0.14404357, 1.45427351, 0.76103773,
                                   0.12167502, 0.44386323, 0.33367433],
           'y': [1.49407907, -0.20515826, 0.3130677, -0.85409574, -2.55298982,
                                  0.6536186, 0.8644362, -0.74216502],
           'z': [2.26975462, -1.45436567, 0.04575852, -0.18718385, 1.53277921,
                                  1.46935877, 0.15494743, 0.37816252]}

########################################
# define all the tokens we will need
########################################
tokens = (
    # Atomics
    "NAME",  # Feature names
    "NUMBER",  # Numeric numbers

    # Binary Ops
    "RELATIONSHIP",  # y ~ x : end result is a tuple of (y, x)

    # Symbols
    "LPAREN",
    "RPAREN",

    # Functions
    "C"  # Expands vector elements into 1-hot
)

########################################
# Building the regexps
########################################

def t_error(t):
    print("Illegal character '%s'" % t.value[0])
    t.lexer.skip(1)

t_ignore = ' '

# Atomics
t_NAME = r'[a-zA-Z_][a-zA-Z0-9_]*'

def t_NUMBER(t):
    r'\d+'
    t.value = str(t.value)
    return t

t_LPAREN = r'\('
t_RPAREN = r'\)'
t_C = r'C'

########################################
# Define the parser
########################################

lex.lex(debug=True)

precedence = (
    ("left", "RELATIONSHIP"),
    ("left", "C")
)

我的解析器是

precedence = (
    ("left", "RELATIONSHIP"),
    ("left", "C")
)


def p_expression_group(p):
    "expression : LPAREN expression RPAREN"
    p[0] = p[2]

def p_expression_number(p):
    "expression : NUMBER"
    p[0] = p[1]

def p_expression_name(p):
    "expression : NAME"
    if p[1] not in em_data:
        raise RuntimeError(f"Term: {p[1]} not found in dataset lookup")

    p[0] = p[1]

def p_error(p):
    print(f"Syntax error at {p.value!r}")

def p_C(p):
    "statement : C LPAREN expression RPAREN"
    print("got in here!")


if __name__ == '__main__':
    s = "C(a)"
    yacc.yacc()
    yacc.parse(s)

一些问题:

  • 如果我把
    语句
    表达式
    放在p_X正则表达式中,这有关系吗?从我所读到的,表达式是减少到单个值的东西,依我看,这意味着一个语句不能减少到单个值。例如
    X=5
    不能减少?在这种情况下,是否会有一个列表,例如
    [“X”,“X:z”…]
    是语句还是表达式?我的直觉告诉我这是表达式,但我想确定

  • 在运行上述所有代码时,我在“(”)处遇到了
    语法错误。我不确定为什么会发生这种情况。我看不出有任何理由应该这样做


  • 您在语法中定义了两个非终结符:
    expression
    statement
    。当您调用
    parse
    时,它将解析您的开始规则。如果您没有使用
    start='rule\u name'
    显式设置开始规则,这将是您在语法中定义的第一个非终结符,即
    expression


    因此,您的解析器拒绝您的输入,因为它不是一个有效的表达式。要让它改为解析语句,您可以移动
    p#C
    ,使其位于第一位,或者可以设置
    start='statement'

    Re#2:Which
    ?我真的不确定…我假设它是字符串中的一个,
    s
    ;当我在没有调用
    C
    的情况下使用s时,没有错误。我已经打开了调试模式,但我在理解
    解析器.out
    文件时遇到了问题。是否可以将它粘贴到这里?1)嗯,当我首先放置
    p\u C
    时(我想你的意思是在所有其他
    p_X
    s之前)我现在在'C'
    处出现
    语法错误。2)你能详细说明我将如何“取消定义”这些非终端吗?另外,如果我不确切知道它将以什么开始,那么
    start=
    如何工作?它可能是语句或变量(另外,在尝试此操作时,我在“C”处遇到了“语法错误”)@IanQuah啊,我以前没有看过你的lexer。现在的问题是你的lexer把
    C
    识别为
    NAME
    ,而不是
    C
    。如果你真的想允许任意的函数名,但你刚开始用
    C
    来保持它的简单性,那么删除
    C
    标记并更改ru就很容易了le to
    NAME LPAREN expression RPAREN
    。但如果确实希望只允许
    C
    作为函数名,则应该这样做。