kaitai_struct icon indicating copy to clipboard operation
kaitai_struct copied to clipboard

Recursive decoding of value

Open LmpOSX opened this issue 3 months ago • 3 comments

Hello, I wonder if the following code is correct or if there is a way to adjust it. It is simplified in the example, but basically it tries to implement a recursive decoding of a value.


      sub_100_modec_t:

        seq:
          - id: value
            type: b12

        instances:
          modec:
            value:  ungray_f(value>>3, 0, 8)

        types:

          ungray_f:
            params:
              - id: c
                type: b12
              - id: pb
                type: b12
              - id: pl
                type: u1

            instances:
              l:
                value: pl-1
              b:
                value: 'pl==0 ? pb : ug'
              ug:
                type: ungray_f(c,'pb^(((pb>>1)^c)&(1<<l)', l)

No matter if I declare ug: value:, ug: type:, or if I put all sentence between '' or just part of it, I will keep getting errors, like:

error: parsing expression 'ungray_f(c,pb^(((pb>>1)^c)&(1<<l), l)' failed on 1:9, expected "::" | CharsWhile(Set( , n)) | "\\\n" | End

or

error: parsing expression 'ungray_f(c,pb^(((pb>>1)^c)&(1<<l), l)' failed on 1:9, expected "or" | CharsWhile(Set( , n)) | "\\\n" | End

or

error: parsing expression 'pl==0 ? pb : ungray_f(c,pb^(((pb>>1)^c)&(1<<l), l)' failed on 1:22, expected "or" | CharsWhile(Set( , n)) | "\\\n" | End

The KSY type, tries to implement the following python code:

def ungray2(c, b=0, l=8):
    if l == 0:
        return b
    l -= 1
    return ungray2(c, b ^ (((b >> 1) ^ c) & (1 << l)), l)

LmpOSX avatar Apr 05 '24 05:04 LmpOSX

The parenthesis in your expression is unbalanced:

-type: ungray_f(c,pb^(((pb>>1)^c)&(1<<l), l)
+type: ungray_f(c,pb^(((pb>>1)^c)&(1<<l)), l)

Mingun avatar Apr 05 '24 05:04 Mingun

@LmpOSX Yes, as @Mingun points out, you're missing a closing parenthesis. Decent editors like VS Code can actually visualize this nicely (although not in a string literal in YAML mode, unfortunately - this is the "Plain Text" mode):

image

generalmimon avatar Apr 05 '24 09:04 generalmimon

Hello, first of all, (late) thanks for the reply. I solved the problem with your help. Also I'would like to ask, if there is a "preferred" or "correct" method to declare recursions in kaitai. I know that probably this kind of process is meant to be implemented in code or in a "process", but I actually like to implement almost all in kaitai. So I implemented the following function that decodes a value which is in a special GRAY code used by aircraft transponders. I implemented it recursively in kaitai, but I have to explicitly activate the recursion to get the result. In the code below, I use the "content" instance from my python code, which uses de recursive instances ungray, but for it to work I have to use the following notation that I don't know if is possible to avoid:

  ungray.u.u.u.u.u.u.u.u.stop

I know how much u's to use because I know the parameter l is 8, as you could see in the line:

            type: ungrayf(unscramble>>3, 0, 8)

But I would like to know if it is possible, to write it in some othe way.

My code:

      sub_100_modec_t:

        instances:
          name:
            value: '"MODEC"'
          title:
            value: '"Mode-C Reply in Gray Notation"'

          is_gray:
            value: 'true'
          unscramble:
            value: '((value>>7)&0o0001)+((value>>8)&0o0002)+((value>>9)&0o0004)+((value<<2)&0o0010)+((value<<1)&0o0020)+((value>>0)&0o0040)+((value>>0)&0o0100)+((value>>1)&0o0200)+((value>>2)&0o0400)+((value<<9)&0o1000)+((value<<8)&0o2000)'
          gray2dec:
            value: '[-1,0,2,1,4,-1,3,12]'
          ungray:
            type: ungrayf(unscramble>>3, 0, 8)
          content:
            value: '((ungray.u.u.u.u.u.u.u.u.stop*5)+((ungray.u.u.u.u.u.u.u.u.stop&1) == 0 ? gray2dec[uscr_value&0b111] : 4 - gray2dec[uscr_value&0b111]))-12'

        types:

          ungrayf:
            params:
              - id: c
                type: b12
              - id: b
                type: b12
              - id: l
                type: u1

            instances:
              stop:
                value: b
                if: l == 0
              u:
                type: ungrayf(c, (b^(((b>>1)^c)&(1<<(l-1)))), l-1)
                if: l > 0

        seq:
          - id: value
            type: b12

Thank you in advance!

LmpOSX avatar May 10 '24 15:05 LmpOSX