AKA "Добавить подузлы, созданные на основе результатов Parser.parseAction, в родительское дерево разбора"
Я пытаюсь проанализировать PHP-файлы, используя PyParsing (какие правила IMHO), в результате чего определения функций были аннотированы аннотациями в стиле JavaDoc. Причина в том, что я хочу хранить информацию о типе таким образом, чтобы ее можно было использовать для создания кода заглушки клиента.
Например:
/*
* @vo{$user=UserAccount}
*/
public function blah($user){ ......
Теперь я смог написать парсер, это очень легко с помощью PyParser. Но PyParser поставляется со встроенным токеном javaStyleComment, который я хотел использовать повторно. Поэтому я проанализировал код, а затем попытался присоединить parseAction, который бы убрал ганк и запустил подпарсер (извините, не уверен в терминологии) и прикрепил результат к родительскому дереву разбора.
Я не могу понять, как это сделать. Код прилагается ниже. Между прочим, я мог бы легко написать свой собственный javaStyleComment, но мне интересно, можно ли вообще разбирать результаты анализа?
Опять же, извините, если мой вопрос не лаконичен, я только новичок в этом деле.
#@PydevCodeAnalysisIgnore
from pyparsing import delimitedList,Literal,Keyword,Regex,ZeroOrMore,Suppress,Optional,QuotedString,Word,hexnums,alphas,\
dblQuotedString,FollowedBy, sglQuotedString,oneOf,Group
import pyparsing
digits = "0123456789"
colon = Literal(':')
semi = Literal(';')
period = Literal('.')
comma = Literal(',')
lparen = Literal('{')
rparen = Literal('}')
lbracket = Literal('(')
rbracket = Literal(')')
number = Word(digits)
hexint = Word(hexnums,exact=2)
text = Word(alphas)
php = Literal("<?php") + Literal("echo") + Literal("?>")
print php.parseString("""<?php echo ?>""")
funcPerm = oneOf("public private protected")
print funcPerm.parseString("""public""")
print funcPerm.parseString("""private""")
print funcPerm.parseString("""protected""")
stdParam = Regex(r"\$[a-z][a-zA-Z0-9]*")
print stdParam.parseString("""$dog""")
dblQuotedString.setParseAction(lambda t:t[0][1:-1])
sglQuotedString.setParseAction(lambda t:t[0][1:-1])
defaultParam = Group(stdParam + Literal("=") + ( dblQuotedString | sglQuotedString | number))
print defaultParam.parseString(""" $dave = 'dog' """)
param = ( defaultParam | stdParam )
print param.parseString("""$dave""")
#print param.parseString("""dave""")
print param.parseString(""" $dave = 'dog' """)
print param.parseString(""" $dave = "dog" """)
csl = Optional(param + ZeroOrMore( Suppress( "," ) + param))
print csl.parseString("""$dog,$cat,$moose """)
print csl.parseString("""$dog,$cat,$moose = "denny" """)
print csl.parseString("""""")
#
funcIdent = Regex(r"[a-z][_a-zA-Z0-9]*")
funcIdent.parseString("farb_asdfdfsDDDDDDD")
#
funcStart = Group(funcPerm + Literal("function") + funcIdent)
print funcStart.parseString("private function dave")
#
#
litWordlit = Literal("(") + csl + Literal(")")
print litWordlit.parseString("""( )""")
funcDef = funcStart + Literal("(") + Group(csl) + Literal(")")
#funcDef.Name = "FUNCTION"
#funcDef.ParseAction = lambda t: (("found %s") % t)
print funcDef.parseString("""private function doggy($bow,$sddfs)""")
funcDefPopulated = funcStart + Literal("(") + Group(csl) + Literal(")") + Group(Literal("{") + ZeroOrMore(pyparsing.CharsNotIn("}")) +Literal("}"))
#funcDef.Name = "FUNCTION"
#funcDef.ParseAction = lambda t: (("found %s") % t)
print funcDefPopulated.parseString("""private function doggy($bow,$sddfs){ $dog="dave" }""")
#" @vo{$bow=BowVo}"
docAnnotations = ZeroOrMore( Group( Literal("@") + text + Suppress(lparen) + param + Literal("=") + text + Suppress(rparen ) ))
print docAnnotations.parseString(""" @vo{$bow=BowVo}""")
def extractDoco(s,l,t):
""" Helper parse action for parsing the content of a comment block
"""
ret = t[0]
ret = ret.replace('/**','')
ret = ret.replace('*\n','')
ret = ret.replace('*\n','\n')
ret = ret.replace('*/','')
t = docAnnotations.parseString(ret)
return t
phpCustomComment = pyparsing.javaStyleComment
#Can't figure out what to do here. Help !!!!!
phpCustomComment.addParseAction(extractDoco)
commentedFuncDef = phpCustomComment + funcDefPopulated
print commentedFuncDef.parseString(
"""
/**
* @vo{$bow=BowVo}
* @vo{$sddfs=UserAccount}
*/
private function doggy($bow,$sddfs){ $dog="dave" }"""
)
*emphasized text*
#example = open("./example.php","r")
#funcDef.parseFile(example)
#f4.parseString("""private function dave ( $bow )""")
#funcDef = funcPerm + Keyword("function") + funcName + Literal("(") + csl + Literal(")")
#print funcDef.parseString(""" private function doggy($bow)""")
=== Обновление
Я обнаружил, что ParseResults, например, имеет метод insert
, который позволяет вам расширять дерево разбора, но все еще не может понять, как это сделать динамически.
Например:
title = oneOf("Mr Miss Sir Dr Madame")
aname = title + Group(Word(alphas) + Word(alphas))
res=aname.parseString("Mr Dave Young")
res
(['Mr', (['Dave', 'Young'], {})], {})
res.insert(3,3)
res
(['Mr', (['Dave', 'Young'], {}), 3], {})