I found a project which has some rudimentary documentation on the file format and even some Python code to parse it:
https://github.com/eriksoe/Schockabsorber
It hasn't been updated since 2013 but still may be useful.
There is also some (rather high level) information over at the Archive Team:
http://fileformats.archiveteam.org/wiki/Shockwave_(Director)
There is no single solution to reversing undocumented file formats. There are basically two approaches you can try:
1. Observation of the producer.
If you happen to have access to a producer of the files (such as a compiler), then you can compile some simple code, look at the output, make some changes, compile it again and compare with the previous output. If you're lucky the changes will be obvious and give at least some clues about the format structure.
2. Observation of the consumer.
If you have a consumer of the file format (such as a player/viewer app), you can try to observe how it parses the file and what steps it performs. You can use dynamic RE, such as monitoring file accesses and memory accesses to the read data, or fully static RE, i.e. just disassemble the parsing code and deduce what it expects and how it deals with the parsed data. Dynamic approach may be easier in practice but it only covers the actually parsed data, not all the possible variations supported by the parser (so having a broad corpus of input files is essential). Static RE is in general more difficult but is the only sure way to find out the real range of supported features.
BTW, both static and dynamic RE may be applied to the producer as well, although in that case you'd have to RE the binary format producing part (output file writer), plus some of the code which produces data for the writer (e.g. the compiler).
P.S. Found an old tool called dirOpener (saved thanks to the Web Archive!) and the site says the following:
The director engine(that translates machine code into actions on your
screen) however does not understand any lingo. Every time you save
your movie, close your script window or press the recompile button,
your lingo code is compiled into machine code that can be executed by
the director engine.
After your lingo code has been compiled director no longer needs it to
execute your file, it just needs the machine code it generated from
your lingo. For you to be able to make changes to your code however,
the lingo is left inside the file. That is, as long as it's
unprotected. The moment you protect your director files the lingo code
is stripped from the file. Also a certain flag is set so that the
director authoring environment can tell it's dealing with a protected
file and the extention is changed to .dxr.
I'm not sure what they mean by "machine code" here. I suspect it may be some kind of bytecode, similar to the AS3 bytecode in Flash, so you may be able to come up with some kind of decompilation process, but don't get your hopes too up.