【问题标题】:Recursive Descent Parser using Python and PLY使用 Python 和 PLY 的递归下降解析器
【发布时间】:2023-11-13 20:14:01
【问题描述】:

对于我的非常基本的问题,我深表歉意,但我在这里真的很挣扎。我需要做一个递归下降解析器。我正在使用 Python 并使用 PLY。我的语法如下:

→ () | ()

, |

|号码

看起来像这样吗?我走远了吗?最终目标是将列表读入数据结构,然后打印出来。

定义 p_list(p) '列表:“(”序列“)” | "("")"' 定义 p_sequence(p) 'sequence : list_el","sequence | list_el' 定义 p_list_el(p) 'list_el:列表 |数字'

如果有人想知道完整的解决方案是什么,我会尽快发布。

【问题讨论】:

  • NUMBER 是否需要定义,还是 PYR 中的特殊定义?
  • 什么是 PYR?你是说 PLY 吗?
  • 我在 Google 上找不到这个假定的 PYR。指向您获得它的位置的链接会有所帮助。虽然根据我所看到的,看起来你确实是说 PLY。
  • 对不起,我的意思是 ply - 错字
  • @Patashu NUMBER 确实需要定义。

标签: python parsing recursive-descent


【解决方案1】:

这就是我的做法:

tokens = ("LBRACKET", "RBRACKET",
          "INTEGER", "FLOAT", "COMMA") # So we can add other tokens
t_LBRACKET = r'\('
t_RBRACKET = r'\)'
t_INTEGER = r'\d+'
t_FLOAT = r'\d+\.\d+'
t_COMMA = r','

def p_list(p):
    """list : LBRACKET sequence RBRACKET
            | LBRACKET RBRACKET"""
    if len(p) == 4:
        p[0] = p[2]
    else:
        p[0] = None

def p_number(p):
    """number : INTEGER
              | FLOAT"""
    p[0] = p[1]

def p_sequence(p):
    """sequence : list_el COMMA sequence
                | list_el"""
    if len(p) == 4:
        p[0] = p[1] + p[3]
    else:
        p[0] = p[1]        

def p_list_el(p):
    """list_el : number
               | list"""
    p[0] = p[1]

编辑:
关于额外标记的快速解释:脚本中的所有内容最终都应该归结为您定义的标记或字符(因此添加是合法的)。通过将它们全部指定为标记,更易于阅读和使用。

【讨论】:

  • 我只是想评论 COMMA 失踪了,但我看到你现在已经添加了它。干得好!
  • 是的,一开始我错过了原帖中的逗号。糟糕!
  • 好的,这非常有帮助。我几乎都遵循它。我唯一的问题是你为什么要检查 len(p) == 4?在这两种情况下不应该在 len(p) == 3 上((LBRACKET 序列 RBRACKET)或(list_el COMMA 序列))吗?
  • 没关系,我现在知道了。在第一种情况下,列表是 p[0],在第二种情况下,序列是 p[0]。
  • 正确 - 基础是令牌,然后其余 (p[1]+) 是右边的所有内容。基本上。
最近更新 更多