标签: ply

如何最好地解析一个简单的语法?

好的,所以我问过一些关于这个项目的小问题,但我对我想出的设计仍然没有多少信心,所以我会在更广泛的范围内提出一个问题.

我正在解析课程目录的先决条件描述.描述几乎总是遵循某种形式,这使我认为我可以解析其中的大多数.

从文本中,我想生成一个关于课程必备关系的图表.(在我解析数据之后,那部分会很简单.)

一些样本输入和输出:

"CS 2110" => ("CS", 2110) # 0

"CS 2110 and INFO 3300" => [("CS", 2110), ("INFO", 3300)] # 1
"CS 2110, INFO 3300" => [("CS", 2110), ("INFO", 3300)] # 1
"CS 2110, 3300, 3140" => [("CS", 2110), ("CS", 3300), ("CS", 3140)] # 1

"CS 2110 or INFO 3300" => [[("CS", 2110)], [("INFO", 3300)]] # 2

"MATH 2210, 2230, 2310, or 2940" => [[("MATH", 2210), ("MATH", 2230), ("MATH", 2310)], [("MATH", 2940)]] # 3  
Run Code Online (Sandbox Code Playgroud)
  1. 如果整个描述只是一个过程,则直接输出.

  2. 如果课程是连接的("和"),则它们都输出在同一列表中

  3. 如果课程脱离("或"),则它们位于不同的列表中

  4. 在这里,我们有"和"和"或". …

python parsing nlp ply pyparsing

27
推荐指数
3
解决办法
3万
查看次数

Lex带有单引号,双引号或三引号

我的目标是像Python一样解析字符串.

问题:如何编写lex以支持以下内容:

  1. "string..."
  2. 'string...'
  3. """multi line string \n \n end"""
  4. '''multi line string \n \n end'''

一些代码:

states = (
        ('string', 'exclusive'),
        )

# Strings
def t_begin_string(self, t):
    r'(\'|(\'{3})|\"|(\"{3}))'
    t.lexer.push_state('string')

def t_string_end(self, t):
    r'(\'|(\'{3})|\"|(\"{3}))'
    t.lexer.pop_state()

def t_string_newline(self, t):
    r'\n'
    t.lexer.lineno += 1

def t_string_error(self, t):
    print("Illegal character in string '%s'" % t.value[0])
    t.lexer.skip(1)


我目前的想法是创建4个独特的状态,将匹配4个不​​同的字符串案例,但我想知道是否有更好的方法.

谢谢你的帮助!

python yacc ply lexer

14
推荐指数
1
解决办法
1602
查看次数

Python - 显示3D点云

我有一个包含人脸3D点云的.PLY文件:我想绘制它并用Python可视化它.

我的.PLY文件只包含顶点和非面.

你能否指出我一个简单的Python库,它将负责绘制3D点云,以便我可以想象它?

重要的是要注意我对绘制MESH不感兴趣,而只是POINT CLOUD.

任何帮助将非常感激.

python 3d ply point-clouds point-cloud-library

10
推荐指数
3
解决办法
3万
查看次数

如何编写正则表达式来匹配字符串文字,其中转义是引号字符的两倍?

我正在使用需要识别FORTRAN字符串文字的ply编写解析器.这些引号用单引号引用,转义字符加倍单引号.即

'I don''t understand what you mean'

是一个有效的转义FORTRAN字符串.

Ply以正则表达式输入.到目前为止我的尝试不起作用,我不明白为什么.

t_STRING_LITERAL = r"'[^('')]*'"

有任何想法吗?

python regex fortran ply

8
推荐指数
1
解决办法
8411
查看次数

PLY:快速解析长项列表?

我在PLY中使用一个相当简单的解析器,我的一个规则采用以下形式:

def p_things(p):
    '''
    things : thing things
    things : thing
    '''
    p[0] = [p[1]]
    if len(p) == 3:
        p[0] += p[2]
Run Code Online (Sandbox Code Playgroud)

输入文件通常是简单的things 列表,因此解析本身并不复杂.但是我的一些输入文件非常大(相当规律地超过100,000行,极端情况下超过1,000,000行).在分析中(通过cProfile和pstats),大部分运行时通过重复调用来占用p_things- 可能是,对things列表中的每个项目进行一次调用.

有没有办法减少这个时间,或者更有效的方法来构建这个规则?到目前为止我看到的大多数答案(以及我发现的规范编译器信息)已经将此方法列为构建可解析项目列表的普遍接受的方式,无论长度如何.

python optimization parsing ply

8
推荐指数
1
解决办法
1483
查看次数

使用PLY解析SQL语句

我知道还有其他工具来解析SQL语句,但我出于教育目的推出了自己的工具.我现在卡住了我的语法..如果你能快速发现错误请告诉我.

SELECT = r'SELECT'
FROM = r'FROM'
COLUMN = TABLE = r'[a-zA-Z]+'
COMMA = r','
STAR = r'\*'
END = r';'
t_ignore = ' ' #ignores spaces

statement : SELECT columns FROM TABLE END

columns : STAR
        | rec_columns

rec_columns : COLUMN
            | rec_columns COMMA COLUMN
Run Code Online (Sandbox Code Playgroud)

当我尝试解析像'SELECT a FROM b;'这样的语句时 我在FROM令牌上遇到语法错误...非常感谢任何帮助!

(编辑)代码:

#!/usr/bin/python
import ply.lex as lex
import ply.yacc as yacc

tokens = (
    'SELECT',
    'FROM',
    'WHERE',
    'TABLE',
    'COLUMN',
    'STAR',
    'COMMA',
    'END',
)

t_SELECT    = r'select|SELECT'
t_FROM      = r'from|FROM'
t_WHERE …
Run Code Online (Sandbox Code Playgroud)

python sql parsing ply context-free-grammar

7
推荐指数
1
解决办法
2031
查看次数

从解析器控制Python PLY词法分析器状态

我正在研究一个简单的SQL选择,如查询解析器,我需要能够捕获可以在某些地方字面上出现的子查询.我发现lexer状态是最好的解决方案,并且能够使用花括号来标记开始和结束.但是,子查询将用括号分隔,而不是用卷曲分隔,括号也可以在其他地方出现,所以我不能成为每个开放状态的状态.解析器随时可以使用此信息,因此我希望在解析器规则中的适当位置调用begin和end.然而这并不起作用,因为词法分析器似乎一次性标记了流,因此令牌在INITIAL状态下生成.这个问题有解决方法吗?以下是我尝试做的概述:

def p_value_subquery(p):
    """
     value : start_sub end_sub
    """
    p[0] = "( " + p[1] + " )"

def p_start_sub(p):
    """
    start_sub : OPAR
    """
    start_subquery(p.lexer)
    p[0] = p[1]

def p_end_sub(p):
    """
    end_sub : CPAR
    """
    subquery = end_subquery(p.lexer)
    p[0] = subquery
Run Code Online (Sandbox Code Playgroud)

start_subquery()和end_subquery()定义如下:

def start_subquery(lexer):
    lexer.code_start = lexer.lexpos        # Record the starting position
    lexer.level = 1
    lexer.begin('subquery') 

def end_subquery(lexer):
    value = lexer.lexdata[lexer.code_start:lexer.lexpos-1]
    lexer.lineno += value.count('\n')
    lexer.begin('INITIAL')
    return value
Run Code Online (Sandbox Code Playgroud)

词法分析器令牌只是用于检测近距离:

@lex.TOKEN(r"\(")
def t_subquery_SUBQST(t):
    lexer.level += 1

@lex.TOKEN(r"\)")
def t_subquery_SUBQEN(t):
    lexer.level -= …
Run Code Online (Sandbox Code Playgroud)

python yacc ply lexer

7
推荐指数
2
解决办法
2625
查看次数

如何防止PLY中的表再生

我在命令行应用程序中使用PLY,我将其打包为要安装的Python egg pip.每次我从命令行运行我的脚本时,都会看到以下消息:

"Generating LALR tables"
Run Code Online (Sandbox Code Playgroud)

此外,parser.out和parsetab.py文件将写入调用脚本的目录.有没有办法用应用程序发送这些文件,以便它不会每次都重新生成表?

python parsing ply

7
推荐指数
2
解决办法
3630
查看次数

如何在两个单独的类中封装PLY的lex和yacc

我正在用PLY编写自己的解析器。我想分别封装lex和yacc

这是Lex类的代码:

class Lex:
    tokens = (
        'NAME', 'NUMBER',
    )

    literals = ['=', '+', '-', '*', '/', '(', ')']

    # Tokens

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

    ...
Run Code Online (Sandbox Code Playgroud)

解析器代码(使用yacc):

class Parser:

    # Parsing rules
    tokens = Lex.tokens

    def p_statement_assign(self, p):
        'statement : NAME "=" expression'
        self.names[p[1]] = p[3]

   ...

    def run(self):
        print self.tokens
        lex.lex(module=Lex)   # ----what should I do here?-----
        parser = yacc.yacc(module=self)
        parser.parse("1+2")
Run Code Online (Sandbox Code Playgroud)

我收到以下错误?必须以Lex实例作为第一个参数调用未绑定的方法t_NUMBER()(改为使用LexToken实例)

我尝试使用module=Lexlex,就像一样yacc.yacc(module=self),但是它没有用,任何人都可以告诉解决方案。

ply python-2.7

7
推荐指数
1
解决办法
641
查看次数

在ast中实现goto

背景:作为一个关于寒假的短期项目,我正在尝试使用Python和PLY实现一种名为Ax(专为图形计算器设计)的编程语言.简要说明:该语言仅允许全局变量并大量使用指针.

我正试图用这种语言实现goto,但不知道该怎么做.

我的一般方法是首先使用PLY将代码解析为ast,然后在我执行时执行它.

例如,声明

If 3
    Disp 4
    Disp 6
End
Run Code Online (Sandbox Code Playgroud)

......会变成......

['PROGRAM', 
  ['BLOCK', 
    ['IF', 
      ['CONDITION', 3], 
      ['BLOCK', 
        ['DISP', 4], 
        ['DISP', 6]
      ]
    ]
  ]
]
Run Code Online (Sandbox Code Playgroud)

...我将以递归方式执行(为了便于阅读,我添加了缩进).

因为ast是树,我不确定如何在不同节点之间跳转.我考虑过将树转换成平面数组,['IF', ['CONDITION', 3], ['DISP', 4], ['DISP', 6]]这样我就可以使用flat-ish数组的索引转到代码中的特定行,但这似乎缺乏一定的优雅,几乎感觉就像一步向后(虽然我可能是错的).

我看过这个,但无法理解它是如何工作的.

任何帮助或提示将不胜感激.

python interpreter goto ply abstract-syntax-tree

6
推荐指数
1
解决办法
1000
查看次数