Создание результатов ParseResults в Pyparsing - PullRequest
1 голос
/ 30 января 2012

Перекрестно в http://pyparsing.wikispaces.com/message/view/home/49765026

Я работаю над проектом синтаксического анализа, в котором мне нужно внедрить некоторые созданные вручную результаты анализа в проанализированный токен. Я прикрепил синтаксический анализ к соответствующему месту в моем коде, и мне, похоже, удалось создать специальный анализатор, который можно добавить обратно в мой более крупный грамматик. dump () и asxml (), кажется, выводят правильно, но другие части моего кода (пытаясь получить доступ к созданным результатам по имени) имеют проблемы. Я могу получить доступ по списку позиций, но не по имени Вполне возможно, что мои ограниченные знания Python меня куда-то напутали, но так как я не смог найти пример создания результатов анализа именно таким образом, я думал, что начну здесь. Вот мой код создания parseresults. tripHeaderCustomFields присоединяется как анализ. Если определенное значение анализируется (т. Е. "TripCode"), то создаются некоторые пользовательские результаты анализа и добавляются обратно в конечный результат.

Если кто-то пытался создать подобные парсультаты вручную, не могли бы вы просмотреть мой код и сказать мне, если вы видите какие-либо явные проблемы? Потребовались часы проб и ошибок, чтобы заставить эту версию работать, и я не удивлюсь, если есть лучший или более правильный путь.

def addCustomField( self, group, name, datatype, value ):
    """
    custom fields:
    Group: ie, specific airline or category - "USAir, "general"
    Name: name of field, ie "linecheck", "Medical", "Deadhead", "IV Pay"
    DataType: string, int, date, time
    Value: value of field, ie. "checked by joe shmo, #2345", or "1st class medical - bryman"
    """
    #TODO: Need to ask for help, some logic problem somewhere. loosing string name somewhere, but xml prints ok!


    prGroup = ParseResults( group, self.NAME.CFGROUP )
    prName = ParseResults( name, self.NAME.CFNAME )
    prDataType = ParseResults( datatype, self.NAME.CFDATATYPE )
    prValue = ParseResults( value, self.NAME.CFVAULE )

    prList = ParseResults( [] )
    prList += prGroup
    prList += prName
    prList += prDataType
    prList += prValue

    customField = ParseResults( [prList], self.NAME.CUSTOMFIELD )


    return customField


def tripHeaderCustomFields( self, tokens ):
    parseSegment = tokens
    if "TripCode" in parseSegment:
        customField = self.addCustomField( "USAir", "PairingCode", "String", parseSegment["TripCode"] )
        if self.NAME.CUSTOMFIELDS in parseSegment:
            parseSegment[self.NAME.CUSTOMFIELDS] += customField
        else :
            parseSegment += ParseResults( [customField], self.NAME.CUSTOMFIELDS )
    if "Charter" in parseSegment[self.NAME.EFFECTIVEDOWS]:
        customField = self.addCustomField( "USAir", "Charter", "Boolean", "True" )
        if self.NAME.CUSTOMFIELDS in parseSegment:
            parseSegment[self.NAME.CUSTOMFIELDS] += customField
        else :
            parseSegment += ParseResults( [customField], self.NAME.CUSTOMFIELDS )
    return tokens

returns a seemingly correct token, 

     <CustomFields>
         <CustomField>
            <Group>USAir</Group>
            <Name>EquipmentChange</Name>
            <DataType>Boolean</DataType>
           <Value>True</Value>
         </CustomField>
         <CustomField>
            <Group>USAir</Group>
            <Name>EquipmentChange</Name>
            <DataType>Boolean</DataType>
            <Value>True</Value>
          </CustomField>
      </CustomFields>

, что приводит к большему результату:

<Trip>
    <TripNumber>8510</TripNumber>
    <EffectiveDOWs>
      <EXCPT>EXCPT</EXCPT>
      <DayOfWeek>MO</DayOfWeek>
      <DayOfWeek>TH</DayOfWeek>
      <DayOfWeek>FR</DayOfWeek>
    </EffectiveDOWs>
    <ReportTime>
      <Hours>21</Hours>
      <Minutes>40</Minutes>
    </ReportTime>
    <TripCode>N</TripCode>
    <EffectiveDateStart>
      <Month>APR</Month>
      <Day>02</Day>
    </EffectiveDateStart>
    <EffectiveDateEnd>
      <Month>APR</Month>
      <Day>27</Day>
    </EffectiveDateEnd>
    <CustomFields>
      <CustomField>
        <Group>USAir</Group>
        <Name>PairingCode</Name>
        <DataType>String</DataType>
        <Value>N</Value>
      </CustomField>
    </CustomFields>
    <RequiredCrew>
      <Captain>1</Captain>
      <FO>1</FO>
    </RequiredCrew>

    .....snip....

</Trip>

1 Ответ

1 голос
/ 09 февраля 2012

Я переработал свой пользовательский код ParseResults, и теперь он работает как положено.Хотел бы я подумать о том, чтобы сделать это в первый раз, так как это было намного легче понять.:) Я склонен изобретать велосипед ... tripHeaderCustomFields присоединяется как ParseAction, а новые ParseResults добавляются к родительскому ParseResults.

Это решает таинственную проблему, с которой я столкнулся при доступе к элементам customField по имени,Я уверен, что это было вызвано тем, что я не совсем понимал, как результаты разбора создаются за кулисами, поэтому для меня это работает намного лучше.

def tripHeaderCustomFields( self, tokens ):
    parseSegment = tokens
    if "TripCode" in parseSegment:
        customField = self.addCustomField( "USAir", "PairingCode", "String", parseSegment["TripCode"], parseSegment )
    if "Charter" in parseSegment[self.NAME.EFFECTIVEDOWS]:
        customField = self.addCustomField( "USAir", "Charter", "Boolean", "True", parseSegment )

def buildCustomFieldString( self, group, name, datatype, value ):
    #TODO: replace any stray "|" that might be in input strings

    text = group + "|" + name + "|" + datatype + "|" + value
    return text

def addCustomField( self, group, name, datatype, value, token ):
    """
    custom fields:
    Group: ie, specific airline or category - "USAir, "general"
    Name: name of field, ie "linecheck", "Medical", "Deadhead", "IV Pay"
    DataType: string, int, date, time
    Value: value of field, ie. "checked by joe shmo, #2345", or "1st class medical - bryman"
       <CustomFields>
          <CustomField>
            <Group>USAir</Group>
            <Name>EquipmentChange</Name>
            <DataType>Boolean</DataType>
            <Value>True</Value>
          </CustomField>
          <CustomField>
            <Group>USAir</Group>
            <Name>EquipmentChange</Name>
            <DataType>Boolean</DataType>
            <Value>True</Value>
          </CustomField>
        </CustomFields>
    """
    pGroup = Word( alphanums )( self.NAME.CFGROUP )
    pName = Word( alphanums )( self.NAME.CFNAME )
    pDatatype = Word( alphanums )( self.NAME.CFDATATYPE )
    pValue = Word( alphanums )( self.NAME.CFVAULE )
    delim = Suppress( "|" )
    customField = Group( pGroup + delim + pName + delim + pDatatype + delim + pValue )( self.NAME.CUSTOMFIELD )
    text = self.buildCustomFieldString( group, name, datatype, value )
    if self.NAME.CUSTOMFIELDS in token:
        token[self.NAME.CUSTOMFIELDS] += customField.parseString( text )
    else :
        token += Group( customField )( self.NAME.CUSTOMFIELDS ).parseString( text )
...