-
Notifications
You must be signed in to change notification settings - Fork 0
/
README
74 lines (44 loc) · 5.35 KB
/
README
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
README.ZR_Scripts
=================
This package is designed to 'compile' Kuju style scripts into a form where they can be interpreted at run time by the train simulator program ZR. The package is also a non-trivial example of how flex (or lex) and bison (or yacc) can be used together to compile a 'C' like language.
Kuju, Kuju Scripts and Copyright
The Kuju company, based in the UK, was responsible for developing the Microsoft Train Simulator (MSTS). One of the problems it faced was how to represent the many types and standards of signalling logic found around the world.
The MSTS program was designed to work with a large number of different routes and, as the logic needed for the different routes could not be known at compile time, another method was needed.
The solution developed was to use a simplified 'C' like language to define the necessary logic. A file containing scripts needed for a particular route is loaded at the start of the program and the scripts interpreted during the running of the program.
The Kuju script file specification is given in document
"How_to_make_Signal_config_and_Script_files.doc"
The file can be generated by running the Microsoft program "techdocs.exe", which is in folder 'techdocs' contained in the first of the two MSTS disks.
In practice the MSTS routes only use a limited number of the language operators, but the language is very flexible and, in principal, can be used for much more complex run-time systems. Other train simulators, such as 'OpenRails', 'Rail Simulator', 'Train Simulator' and 'Train Sim World', continue to use the scripts for both the original MSTS routes and for the many other routes that have been developed.
The position of copyright over the code is, unfortunately, a bit vague. Kuju developed the code for Microsoft, who presumably held the original copyright. However Microsoft stopped its own development and instead made the files and specification widely available, to allow others to develop the program further. This has been done by OpenRails and others, but, after fifteen or more years, everyone is still very wary about providing public copies of any of the MSTS files and documentation.
For this reason, the only signal script file provided here, for testing, is the one from the Australian Zig-zag railway route. I thank the developers of the route.
ZR and the Signal Scripts
There are many ways signal scripts can be processed during the running of a train simulator program. The method adopted for the ZR program is to used the programs 'flex' (a free version of lex) and 'bison' (a GNU program related to 'yacc') to generate the files 'lex.yy.c', 'y.tab.c' and 'y.tab.h'. These files together with 'sigscr.c' and 'sigscr.h' are then included when compiling the rest of the ZR code.
When the program starts, ZR uses routines contained in the files to read the appropriate signal script file. The file 'lex.yy.c' contains a routine to split the signal script file into tokens. These are passed to a routine in 'y.tab.c', which parses the script, i.e. recognises the different elements of the underlying program.
The routines in file 'load_sigscr_file.c', are then used to store the results in a lisp style tree structure in which the nodes and leafs represent mathematical and logical operators, subroutine names and variables. The routines are based on those published by Tom Niemann in his book "Lex & Yacc Tutorial" [https://www.epaperpress.com/lexandyacc/] and the associated calculator source code. Niemann also provides an alternative storage method in which the script code is stored as an array of pseudo machine code instructions.
Once the ZR program has finished the startup sequence, it enters a loop in which it regularly updates the state of each signal. It does this by using a tree-walk scheme to visit and process the set of nodes appropriate to the signal. It uses a simple stack for temporary variables.
This process ends with the script defining a variable 'draw_state'. Depending on the signal, this indicates to the program which lights to illuminate, their colours, the position of a semaphore arm, and the state of any other elements, such as illuminated messages or the use of flashing lights.
Note that although the present code works with the standard MSTS routes, the Australian Zig-Zag route and related routes, a few of the operators defined in the signal script specification are missing in the current version of the code. Similarly ZR does not include code corresponding to all of the subroutines defined in the specification.
Input files
The files provided are:
bas.l :: Definition of tokens used by the scripts
bas.y :: Parsing of the scripts
main.c :: A test program
makefile ::
load_sigscr_file.c :: Read file, create tree.
sigscr.h :: Tree structure specifications
Compilation and Testing
The command 'make' should result in output:
bison -dy -Dparse.trace bas.y
gcc -c y.tab.c
flex bas.l
gcc -c lex.yy.c
gcc -c load_sigscr_file.c
gcc -c main.c
gcc lex.yy.o y.tab.o load_sigscr_file.o main.o -o main
The command ./main' should then generate output, matching that saved in file 'test.out'.
Files copied to ZR
lex.yy.c
y.tab.c
y.tab.h
load_sigscr_file.c
sigscr.h