7

別名「Parser.parseAction の結果から構築されたサブノードを親解析ツリーに追加する」

関数定義にJavaDocスタイルの注釈が付けられているPyParsing(これはIMHOのルールです)を使用してPHPファイルを解析しようとしています。その理由は、クライアント スタブ コードの生成に使用できる方法で型情報を格納したいからです。

例えば:

/*
*  @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], {})
4

1 に答える 1

2

まず、私は恋をしています。PyParser は、私が今まで使った中で最も優れたライブラリの 1 つに違いありません。第二に、解決策は本当に、本当に、簡単でした。

これが私がそれを修正した方法です:

docAnnotations = ZeroOrMore( Group( ZeroOrMore(Suppress("*")) +   Suppress(Literal("@")) + Suppress(Literal("vo")) + Suppress(lparen) + param + Literal("=") + text  + Suppress(rparen ) ))
print docAnnotations.parseString(""" @vo{$bow=BowVo}""")

def extractDoco(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('*/','')
    print ret
    return docAnnotations.parseString(ret)  

phpCustomComment = pyparsing.javaStyleComment

最後のセクション:

print commentedFuncDef.parseString(
                                   """
                                   /**
                                   * @vo{$bow=BowVo}
                                   * @vo{$sddfs=UserAccount}
                                   */
                                   private function doggyWithCustomComment($bow,$sddfs){ $dog="dave" }"""
                                   )

結果:

[['$bow', '=', 'BowVo'], ['$sddfs', '=', 'UserAccount'], ['private', 'function', 'doggyWithCustomComment'], '(', ['$bow', '$sddfs'], ')', ['{', ' $dog="dave" ', '}']]
于 2012-02-22T19:25:24.313 に答える