Review current parser parsing C/AL object into a PWSH variable with some predetermined structure. I need the parser is able to capture all properties that can be found in the table object structure. Consider, for example fields in the example TAB52103.txt  don't have all possible properties and there can be more. The current parser doesn't work correctly and well.

Current parser:
```
function Parse-CAL {
    param (
        [string]$calCode
    )

    $result = @{
        objectType = ''
        objectId = ''
        objectName = ''
        objectProperties = @{}
        properties = @{}
        fields = @()
    }

    Write-Host "Parsing object header..."
    if ($calCode -match 'OBJECT (\w+) (\d+) (.+)') {
        $result.objectType = $matches[1]
        $result.objectId = $matches[2]
        $result.objectName = $matches[3].Trim()
        Write-Host "Object Type: $($result.objectType)"
        Write-Host "Object ID: $($result.objectId)"
        Write-Host "Object Name: $($result.objectName)"
    } else {
        Write-Host "Failed to parse object header"
    }

    Write-Host "Parsing object properties..."
    if ($calCode -match 'OBJECT-PROPERTIES\s*\{([^}]+)\}') {
        $objectPropertiesText = $matches[1]
        $objectPropertyMatches = [regex]::Matches($objectPropertiesText, '(\w+)=(.+?);')
        foreach ($match in $objectPropertyMatches) {
            $key = $match.Groups[1].Value
            $value = $match.Groups[2].Value.Trim()
            $result.objectProperties[$key] = $value
            Write-Host "Object Property: $key = $value"
        }
    } else {
        Write-Host "Failed to parse object properties"
    }

    Write-Host "Parsing properties..."
    if ($calCode -match 'PROPERTIES\s*\{([^}]+)\}') {
        $propertiesText = $matches[1]
        $propertyMatches = [regex]::Matches($propertiesText, '(\w+)=(.+?);')
        foreach ($match in $propertyMatches) {
            $key = $match.Groups[1].Value
            $value = $match.Groups[2].Value.Trim()
            $result.properties[$key] = $value
            Write-Host "Property: $key = $value"
        }
    } else {
        Write-Host "Failed to parse properties"
    }

    Write-Host "Parsing fields..."
    if ($calCode -match 'FIELDS\s*\{(?:[^{}]|\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*\})*\}') {
        $fieldsText = $matches[0]
        Write-Host "Fields text found. Length: $($fieldsText.Length)"
        $fieldMatches = [regex]::Matches($fieldsText, '\{([^}]+)\}')
        Write-Host "Number of field matches: $($fieldMatches.Count)"
        foreach ($fieldMatch in $fieldMatches) {
            $fieldContent = $fieldMatch.Groups[1].Value
            $field = @{
                id = ''
                name = ''
                type = ''
                properties = @{}
            }

            if ($fieldContent -match '^\s*(\d+)\s*;([^;]*);([^;]+);([^;]+);(.*)$') {
                $field.id = $matches[1].Trim()
                $field.name = $matches[3].Trim()
                $field.type = $matches[4].Trim()
                Write-Host "Field: ID=$($field.id), Name=$($field.name), Type=$($field.type)"

                $fieldPropertiesText = $matches[5]
                $fieldPropertiesMatches = [regex]::Matches($fieldPropertiesText, '(\w+)=([^;]+)')
                foreach ($propMatch in $fieldPropertiesMatches) {
                    $propName = $propMatch.Groups[1].Value
                    $propValue = $propMatch.Groups[2].Value.Trim() -replace '^"|"$', ''
                    $field.properties[$propName] = $propValue
                    Write-Host "  Field Property: $propName = $propValue"
                }
            } else {
                Write-Host "Failed to parse field content: $fieldContent"
            }

            $result.fields += $field
        }
    } else {
        Write-Host "Failed to parse fields"
    }

    return $result
}


$file = 'C:\BC\Projects\ConvertCrane\Conversion\CALParser\TAB52103.txt'
$fileContent = Get-Content $file -Raw 

$result = Parse-CAL $fileContent
$result | ConvertTo-Json -Depth 10 | Out-File 'C:\BC\Projects\ConvertCrane\Conversion\CALParser\TAB52103.json' 
```

# the source file
```
OBJECT Table 52103 Crane User
{
  OBJECT-PROPERTIES
  {
    Date=29-11-19;
    Time=00:05:51;
    Modified=Yes;
    Version List=NPK1.00;
  }
  PROPERTIES
  {
    CaptionML=ENU=Crane User;
    LookupPageID=Page52103;
    DrillDownPageID=Page52103;
  }
  FIELDS
  {
    { 1   ;   ;User Type           ;Option        ;OnValidate=BEGIN
                                                                IF ("User Type" <> xRec."User Type") THEN BEGIN
                                                                  IF (xRec."User Type" <> "User Type"::" ") THEN BEGIN
                                                                    VALIDATE("User Code",'');
                                                                  END;
                                                                END;
                                                              END;

                                                   CaptionML=ENU=User Type;
                                                   OptionCaptionML=ENU=" ,Resource";
                                                   OptionString=[ ,Resource];
                                                   NotBlank=Yes }
    { 3   ;   ;User Code           ;Code20        ;TableRelation=IF (User Type=CONST(Resource)) Resource WHERE (Type=CONST(Person));
                                                   OnValidate=BEGIN
                                                                TESTFIELD("User Code");
                                                              END;

                                                   CaptionML=ENU=User Code;
                                                   NotBlank=Yes }
    { 11  ;   ;Default Geo Area Code;Code20       ;TableRelation="Crane Geo Area";
                                                   CaptionML=ENU=Default Geo Area Code }
  }
  KEYS
  {
    {    ;User Type,User Code                     ;Clustered=Yes }
  }
  FIELDGROUPS
  {
  }
  CODE
  {

    BEGIN
    {
      NPK1.00/JAVA/20191128  CASE 357428 Object created - Crane User.
    }
    END.
  }
}
```