Processing Include Files ######################## One of the more complicated aspects of parsing the |OSC| language us dealing with **include** and **use** files. Basically, when |OSC| encounters one of these lines, it stops processing the current file, and starts processing the specified include or use file. For *include* files, the effect is as though the included file was literally copied in-plqce into the original file. For *use* files, only the module specification lines are processed. We will deal with *use* files later. The basic format of an *include* line is handled using the **fileinclude** rule .. literalinclude:: ../scadparser/ebnf/scad.ebnf :lines: 88-100 :caption: scadparser/ebnf/scad.ebnf Parsing this line is simple, making the parser actually process the included file is not so simple. .. note:: Notice that the rule for a **filename** is actually a bad one. I cheated and accept any characters up to the closing right angle bracket. This needs to be fixed with a better regular expression, but it will work for now. Here is a basic test to check that an include line is properly formed: .. literalinclude:: ../tests/test_includes.py :linenos: :caption: tests/test_includes.py Include File Handling ********************* Now that we have a rule that will properly parse the include line, we need to figure out ow to cause the parser to actually handler the named file. This requires teaching our parser to fire off |PY| code when it deals with the rule. TatSu_ provides a nice way to do this. Through something called *Semantic Actions* we can call a |PY| function with the same name as the rule in question when the parser processes that rule. We need to define a new |PY| class for these actions: .. literalinclude:: ../scadparser/ScadSemantics.py :linenos: :caption: scadparser/ScadSemantics.py Basically, what this code does is to launch another parser for the same language, and collects the **AST** generated by that new parser. It will return that new **AST** as the result of processing the *include* file to the original parser which will add it to its current parse results. Here is a test program that shows this result; .. literalinclude:: ../sandbox/step03.py :linenos: :caption: sandbox/step03.py And here is he (messy) result: .. command-output:: python sandbox/step03.py :cwd: ../ This **AST** is a bit complex, but it will be simple enough to process later.