Saya mengalami kesulitan menemukan cara untuk mengabaikan struktur jika bersarang di jenis struktur lain. Dalam contoh di bawah ini saya memiliki structure_a yang saya coba uraikan, tetapi dalam hasil saya, saya juga mendapatkan kecocokan untuk structure_a yang bersarang di struktur lain. Saya tidak ingin pyparsing mencocokkannya kecuali saya mencocokkan struktur luar terlebih dahulu. Bagaimana saya akan melakukan itu?

self.LBRACE, self.RBRACE, self.LBRACK, self.RBRACK, self.SEMI, self.COMMA, self.DOUBLEQUOTE = map(pp.Suppress, '{}[];,"')

def parse(self, data):
    template = CaselessKeyword("structure_a")

    words = Word(alphanums + "_" + "." + "[" + "]")

    recursive_grammar = Forward()
    recursive_grammar <<= (
        Group(words("type") + words("name") + self.LBRACE +      
              ZeroOrMore(recursive_grammar) + self.RBRACE |

              words("name") + self.LBRACE + 
              ZeroOrMore(recursive_grammar) + self.RBRACE |

              self.LBRACE + ZeroOrMore(recursive_grammar) + self.RBRACE |

              self.LBRACE + ZeroOrMore(words("type")) + self.RBRACE) |

        Group(words("name") + self.EQUAL + recursive_grammar |

              ZeroOrMore(words("type")) + words("name") + self.EQUAL + 
              words("value") + Optional(self.COMMA) |

              words("name") + self.EQUAL + words("value") + 
              Optional(self.COMMA))
    )

    grammar = (template("category") + words("type") + words("name") +
               self.LBRACE + ZeroOrMore(recursive_grammar)("members") + 
               self.RBRACE + Optional(cStyleComment)("short_description"))

    result = grammar.searchString(data)

    return result
# I want to match this structure
structure_a type name { 
    variable = 1
}

structure_b name {
    # I only want to match a nested structure_a if I create a new 
    # grammar to match structure_b that have structure_a nested in it.    
    # Otherwise I want to ignore nested structure_a
    structure_a type name { 
        variable = 2
    }
}

Saat ini tata bahasa saya cocok dengan hal-hal yang ada di structure_b serta elemen tingkat atas. Saya tidak ingin pyparsing mencocokkan hal-hal di structure_b kecuali saya secara eksplisit mencocokkan structure_b terlebih dahulu.

1
Christopher Lee 31 Juli 2019, 16:31

1 menjawab

Jawaban Terbaik

Setelah menulis pertanyaan dan mempostingnya dan mengambil waktu dari masalah, saya pikir saya telah menemukan solusi. Saya pikir alasan itu cocok dengan stucture_a bersarang adalah karena tidak dapat menemukan kecocokan untuk structure_b luar sehingga parser hanya pindah ke baris teks berikutnya dan parser tidak tahu bahwa structure_a bersarang bersarang. Jadi saya menulis ulang kode saya untuk ini dan sepertinya berhasil.

self.LBRACE, self.RBRACE, self.LBRACK, self.RBRACK, self.SEMI, self.COMMA, self.DOUBLEQUOTE = map(pp.Suppress, '{}[];,"')

def parse(self, data):
    template1 = CaselessKeyword("structure_a")
    template2 = CaselessKeyword("structure_b")

    words = Word(alphanums + "_" + "." + "[" + "]")

    recursive_grammar = Forward()
    recursive_grammar <<= (
        Group(words("type") + words("name") + self.LBRACE +  
              ZeroOrMore(recursive_grammar) + self.RBRACE |

              words("name") + self.LBRACE + ZeroOrMore(recursive_grammar) + 
              self.RBRACE |

              self.LBRACE + ZeroOrMore(recursive_grammar) + self.RBRACE |

              self.LBRACE + ZeroOrMore(words("type")) + self.RBRACE | 

              # added the nested structure to my recursive grammar
              template1("category") + words("type") + words("name") +
              self.LBRACE + ZeroOrMore(recursive_grammar)("members") + 
              self.RBRACE + Optional(cStyleComment)("short_description")) |

        Group(words("name") + self.EQUAL + recursive_grammar |

              ZeroOrMore(words("type")) + words("name") + self.EQUAL + 
              words("value") + Optional(self.COMMA) |

              words("name") + self.EQUAL + words("value") + Optional(self.COMMA))
    )

    grammar = (template1("category") + words("type") + words("name") +
               self.LBRACE + ZeroOrMore(recursive_grammar)("members") + 
               self.RBRACE + Optional(cStyleComment)("short_description") | 

               # Match stucture_b
               template2("category") + words("name") + self.LBRACE +
               ZeroOrMore(recursive_grammar)("members") + self.RBRACE + 
               Optional(cStyleComment)("short_description")
    )

    result = grammar.searchString(data)

    return result
# Same example from question...

structure_a type name { 
    variable = 1
}

structure_b name {
    structure_a type name { 
        variable = 2
    }
}
# Results...

Name: name
Category: structure_a
Type: type

['variable', '=', '1']



Name: name
Category: structure_b
Type: 

['structure_a', 'type', 'name', ['variable', '=', '2']]
0
Christopher Lee 1 Agustus 2019, 14:03