g | x | w | all
Bytes Lang Time Link
016Jelly250219T182804ZUnrelate
01605AB1E250220T182618ZKevin Cr
069JavaScript Node.js250219T170501Zl4m2
044Retina 0.8.2250220T083108ZNeil
033Charcoal250220T013211ZNeil

Jelly, 18 16 bytes

-*×ỊÄṂÐƤ=$ƤḋẒŻxḂ

Try it online!

Not sure if this has massive room for improvement or if Jelly is just that bad at balanced string stuff. Maps

∘ <-> 1
⋅ <-> 2
⊙ <-> 3
⊃ <-> 0

This mapping was chosen so that

The idea is that, for every stack element selected by an id or dip, its depth is the number of gaps and dips which apply to it(s selector), either directly or to a fork containing it--which is the number of gaps and dips to its left minus those which apply to a different branch of a fork, lying between the fork operator and an id.

    Ä               Cumulative sums of
-*                  -1 to the power of each input element
  ×Ị                or 0 if the element isn't an id or dip.
         $Ƥ         For each prefix,
        =           does each element
     ṂÐƤ            have no strictly smaller element to its right?
           ḋ        Sum the comparisons in each prefix which correspond to
            Ẓ       dip or gap.
             Ż      Prepend a 0,
              x     then keep only elements at the same positions as
               Ḃ    an id or dip in the original input.

Jelly, 21 bytes

0W
Ṫ‘
ÇŻ
Ṫ;Ṫ
Uṭ@ṛĿ¥ƒḟ

Try it online!

-0 but function compatibility thanks to Jonathan Allan

Horrendously ungolfed... except I'm struggling to actually golf it at all. Maps

∘ <-> 1
⋅ <-> 2
⊙ <-> 3
⊃ <-> 4

although any improvement is likely to hinge on changing this mapping for easy-to-check and possibly combinable conditions, since it's (almost) completely arbitrary.

0W          Link 1: [0]
Ṫ‘          Link 2: Pop the last element and increment it.
ÇŻ          Link 3: Call link 2 then prepend 0 to its result.
Ṫ;Ṫ         Link 4: Pop the last two elements and concatenate them reversed.

Uṭ@ṛĿ¥ƒḟ    Main link:
U           Reverse the input,
     ¥ƒ     then reduce starting from the input by:
 ṭ@         append to the accumulator
    Ŀ       the result of calling on the accumulator
   ṛ        the link at the index provided by the current element being reduced.
       ḟ    Filter out the scalars from the original input.

05AB1E, 16 bytes

ÎvyiDëydi=}>y_i\

Uses 012⋅ for identify, fork, dip, gap (or ∘⊃⊙⋅) respectively.

Try it online or verify all test cases.

Explanation:

Î         # Push 0 and the input
 v        # Pop the input, and loop over its characters `y`:
  yi      #  If `y` is a 1 (aka, it's a Fork):
    D     #   Duplicate the current top value, and continue with the next iteration
   ë      #  Else:
    ydi   #   If `y` is a number >=0 (aka, it's an Identity or Dip):
       =  #    Print the top of the stack with trailing newline (without popping)
      }   #   Close the inner if-statement
    >     #   Increase the top value by 1
    y_i   #   If `y` is 0 (aka, it's an Identity):
       \  #    Discard the top value from the stack

JavaScript (Node.js), 69 bytes

x=>x.flatMap(t=>t>2?x.push(i)&&[]:(s=i++,t>1?i=x.pop():0,t?s:[]),i=0)

Try it online!

⋅⊙∘⊃ map to 0123

Retina 0.8.2, 44 bytes

(?<=(∘()|⊃(?<-2>)?|.(\2|()))*)[⊙∘]
$#4 
⋅|⊃

Try it online! Link includes test cases and uses original characters for convenience, but obviously I could just substitute them with ASCII characters. Explanation:

(?<=(∘()|⊃(?<-2>)?|.(\2|()))*)[⊙∘]
$#4 

Match a dip or id, replacing it with the count of how many dips or gaps there are to its left, except while scanning to the left, use .NET balancing groups to keep track of whether there are ids whose forks have not yet been matched in which case don't count any intervening dips or gaps. (Technically since this is a lookbehind the parts of the alternation should be reversed as they match right-to-left but it doesn't matter as the second part is always zero width.)

⋅|⊃

Delete the gaps and forks.

Charcoal, 33 bytes

⊞υ⁰FS≡ιF⊞υ↨υ⁰«≔⊟υθF⁻Iι⊞υ⊕θF⁻Gι⟦Iθ

Try it online! Link is to verbose version of code. Takes input using DFGI for dip, fork, gap and id, or Try it online! using the original characters. Outputs the order on separate lines. Explanation:

⊞υ⁰

Start with no items consumed from the stack.

FS≡ι

Switch over each character of the input.

F⊞υ↨υ⁰«

If it's an F then duplicate the number of items consumed, otherwise:

≔⊟υθ

Get the number of items consumed into a variable.

F⁻Iι⊞υ⊕θ

If the character is not an I then save one more item consumed. (In the case of I the previously duplicated F value gets used for subsequent commands.)

F⁻Gι⟦Iθ

If the character is not a G then output the current number of items consumed.