python - 如何使用 Pyparsing 解析嵌套函数调用?

标签 python nested grammar pyparsing function-calls

我正在开发一个 css 解析器,但不知道如何解析嵌套函数调用,例如 alpha(rgb(1, 2, 3), 0.5)

这是我的代码:

# -*- coding: utf-8 -*-


from pyparsing import * #, Word, alphas, OneOrMore, countedArray, And, srange, hexnums,  Combine, cStyleComment

from string import punctuation
from app.utils.file_manager import loadCSSFile, writeFile
from pyparsing import OneOrMore, Optional, Word, quotedString, delimitedList,  Suppress
from __builtin__ import len

# divide tudo por espaços, tabulações e novas linhas
words = ZeroOrMore(cStyleComment | Word(printables))

digit = '0123456789'; underscore = '_'; hyphen =  '-'
hexDigit = 'abcdefABCDEF' + digit
letter = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
az_AZ_underscore = underscore + letter;  
az_AZ_09_underscore = az_AZ_underscore + digit; 
az_AZ_hyphen = hyphen + letter;
az_AZ_09_hiphen = az_AZ_hyphen + digit;
LPAR = Suppress('('); RPAR = Suppress(')')

# identifiers
identifier = Combine(Word(az_AZ_underscore) + Optional(Word(az_AZ_09_underscore)))
# identifiers
identifier_reserved = Combine(Word(az_AZ_hyphen) + Optional(Word(az_AZ_09_hiphen)))

# numbers
hexadecimal = Word(hexnums, min=1)
integer = Word(digit, min=1)
decimal = Combine('.' + integer | integer + Optional('.' + integer))


# value values
color_hex = Combine('#' +  hexadecimal ) 
at_identifier =  Combine('@' + identifier)
arg = at_identifier | color_hex | decimal | quotedString 




function_call = identifier + LPAR + Optional(delimitedList(arg)) + RPAR

value =  Group(color_hex | at_identifier | function_call)

print(value.parseString('a(b())'))

我想做一些类似arg = at_identifier |十六进制颜色 |十进制 |引用字符串 | function_call 但这是不可能的,因为变量是 function_call 尚未声明。

我如何使用 Pyparsing 解析嵌套函数调用?

最佳答案

你们真的很亲密。要定义这样的递归语法,您需要前向声明嵌套表达式。

如您所见,这:

arg = at_identifier | color_hex | decimal | quotedString
function_call = identifier + LPAR + Optional(delimitedList(arg)) + RPAR

仅解析带有本身不是函数调用的 args 的函数调用。

要递归地定义它,首先使用 Forward() 定义一个空的占位符表达式:

function_call = Forward()

我们还不知道这个表达式中会包含什么,但我们知道它将是一个有效的参数类型。由于它现在已经声明,我们可以使用它:

arg = at_identifier | color_hex | decimal | quotedString | function_call

现在我们已经定义了 arg,我们可以定义将进入 function_call 的内容。我们必须使用一个运算符来修改 function_call 而不是重新定义它,而不是使用使用“=”的普通 Python 赋值。 Pyparsing 允许您使用 <<= 或 << 运算符(首选第一个):

function_call <<= identifier + LPAR + Optional(delimitedList(arg)) + RPAR

现在这足以解析给定的示例字符串,但是您已经看不到实际的嵌套结构。如果您像这样对函数调用进行分组:

function_call <<= Group(identifier + LPAR + Group(Optional(delimitedList(arg))) + RPAR)

您将始终从函数调用(命名和解析的参数)中获得可预测的结构,并且函数调用本身将被分组。

关于python - 如何使用 Pyparsing 解析嵌套函数调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23331004/

相关文章:

c - 一元运算符歧义

ruby - 以编程方式从字符串派生正则表达式

python - Django - 如何从模板中获取 {% block %} 标签的内容

python - 如何检查for循环中的特定值然后结束它?

css - 嵌套 DIV - 嵌套 DIV 不占用高度?

css - 是否可以使用响应式方法将 col-xs-1 嵌套到较小的部分 - bootstrap

python - 使用 Requests 包时出现 SSL InsecurePlatform 错误

python - 如何使用户输入在 python 3 中不区分大小写?

json 忽略标记 ("-") 不适用于嵌入式子结构

ANTLR:回溯和前瞻的区别?