Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
String 在ply(python)中解析具有特定格式的文件_String_File_Parsing_Multiline_Ply - Fatal编程技术网

String 在ply(python)中解析具有特定格式的文件

String 在ply(python)中解析具有特定格式的文件,string,file,parsing,multiline,ply,String,File,Parsing,Multiline,Ply,我的ply有一个问题,我必须接收一个带有令牌列表和语法(bnf)的文件,我编写了一个语法来识别输入,它几乎可以工作(只是一些小问题,我们正在解决它们),例如,这是一个有效的输入文件 #tokens = NUM PLUS TIMES exp : exp PLUS exp | exp TIMES exp exp : NUM (在这种情况下,我们不关心含糊不清的语法或其他问题,这是一个输入示例) 单独解析每一行很好,但我想用以下规则解析整个文件: def p_S(p): '''S : T N U''

我的ply有一个问题,我必须接收一个带有令牌列表和语法(bnf)的文件,我编写了一个语法来识别输入,它几乎可以工作(只是一些小问题,我们正在解决它们),例如,这是一个有效的输入文件

#tokens = NUM PLUS TIMES
exp : exp PLUS exp | exp TIMES exp
exp : NUM
(在这种情况下,我们不关心含糊不清的语法或其他问题,这是一个输入示例)

单独解析每一行很好,但我想用以下规则解析整个文件:

def p_S(p):
'''S : T N U'''
print("OK")
  • #标记必须只在第一行,所以如果在语法之后有一个#tokens声明,它是无效的
  • 每行“代码”后面可以有0行或多行空行
  • 你可以有任意多的语法规则
我尝试使用循环分别扫描和解析每一行,但我无法控制rirst(非常重要)规则,因此我在.py文件中尝试了以下方法:

我定义了t\u NLINEA(新行),但在将\n字符用作文本时遇到问题,并且文件是使用rU模式打开的,以避免\r\n或\n字符冲突,因此我添加了以下规则:

def p_S(p):
'''S : T N U'''
print("OK")
def p_N(p): “N:NLINEA N” 通过

def p_N2(p): ''N''' 通过

def p_(p): “U:R N U” 通过

def p_U2(p): ''你:'' 通过

(如上所述,我必须使用N规则,因为ply在语法中不接受\N文本,我将\N添加到“literals”变量)

T是解析#tokens声明的规则,R用于解析语法规则,如果我在单行字符串中使用T和R,它们可以正常工作,但是当我添加我上面写的产品时,我在解析First-gramar规则时会出现语法错误,例如
a:bc
我在
中出现语法错误:

有什么建议吗? 谢谢

Ply试图根据您的规则找出一个“开始规则”。根据您编写的内容,它将使“exp”成为开始规则,即每个字符串或文件只有一个表达式。如果需要多个表达式,则可能需要表达式列表:

def p_exp_list(p):
    """exp_list :
                | exp_list exp
    """
    if len(p) == 1:
       p[0] = []
    else:
       p[0] = p[1] + [p[2]]
那么您的起始规则将是“exp\u list”。这将允许每行上有多个表达式。如果要将每行限制为一个表达式,那么:

def p_line_list(p):
    """line_list :
                 | line_list line
    """
    if len(p) == 1:
       p[0] == []
    else:
       p[0] = p[1] + [p[2]]

def p_line(p):
    """line : exp NL"""
    p[0] = p[1]
我不认为可以使用换行符作为文字(因为它可能会弄乱正则表达式)。您可能需要更具体的令牌规则:

t_NL = r'[\r*\n]'
很确定这会起作用,但还没有尝试过,因为没有足够的时间继续下去

至于“#令牌”行,如果它没有出现在其他任何地方,您可以跳过它:

def t_COMMENT(t):
    r'#.*$'
    pass # ignore this token

您好,谢谢您的建议,我仍然对新行字符有问题,我不知道这是ply还是python问题,或者其他我做错了的事情,即使使用您的解决方案,我在第二行也总是遇到语法错误,但无论如何,谢谢,我将分别解析第一行,并使用剩余的行作为输入,而R规则……Ply只是构建了一个非常大的正则表达式,它使用Python的“re”模块。正则表达式“”不接受“\n”,这是一个特性,而不是一个问题。您可以使用“#(.|\n)*$”,但这意味着一条注释行将丢弃注释行后面的所有内容。