Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Recursive decoding of value #1102

Open
LmpOSX opened this issue Apr 5, 2024 · 3 comments
Open

Recursive decoding of value #1102

LmpOSX opened this issue Apr 5, 2024 · 3 comments
Labels

Comments

@LmpOSX
Copy link

LmpOSX commented Apr 5, 2024

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)
@Mingun
Copy link

Mingun commented Apr 5, 2024

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)

@generalmimon
Copy link
Member

@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

@LmpOSX
Copy link
Author

LmpOSX commented May 10, 2024

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!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants