summaryrefslogtreecommitdiff
path: root/web/yacco2/o2linker
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /web/yacco2/o2linker
Initial commit
Diffstat (limited to 'web/yacco2/o2linker')
-rw-r--r--web/yacco2/o2linker/Makefile86
-rw-r--r--web/yacco2/o2linker/Makefile_Edit_cweb36
-rw-r--r--web/yacco2/o2linker/bugs.w173
-rw-r--r--web/yacco2/o2linker/common_externs.cpp379
-rw-r--r--web/yacco2/o2linker/common_externs.h28
-rw-r--r--web/yacco2/o2linker/globals.h26
-rw-r--r--web/yacco2/o2linker/includes.w42
-rw-r--r--web/yacco2/o2linker/intro.w394
-rw-r--r--web/yacco2/o2linker/makefile_APPLE110
-rw-r--r--web/yacco2/o2linker/makefile_GNU82
-rw-r--r--web/yacco2/o2linker/makefile_SOLARIS141
-rw-r--r--web/yacco2/o2linker/o2linker.cpp1132
-rw-r--r--web/yacco2/o2linker/o2linker.h60
-rw-r--r--web/yacco2/o2linker/o2linker.w20
-rw-r--r--web/yacco2/o2linker/o2linker_defs.cpp99
-rw-r--r--web/yacco2/o2linker/o2linker_defs.w92
-rw-r--r--web/yacco2/o2linker/o2linker_doc.w3195
-rw-r--r--web/yacco2/o2linker/o2linker_externs.cpp54
-rw-r--r--web/yacco2/o2linker/o2linker_externs.h32
-rw-r--r--web/yacco2/o2linker/o2linker_externs.w147
-rw-r--r--web/yacco2/o2linker/o2linker_types.h142
-rw-r--r--web/yacco2/o2linker/o2linker_types.w133
-rw-r--r--web/yacco2/o2linker/pms.w38
-rw-r--r--web/yacco2/o2linker/prog.w1134
-rw-r--r--web/yacco2/o2linker/sampleoutput.w23
-rw-r--r--web/yacco2/o2linker/testsuites.w15
26 files changed, 7813 insertions, 0 deletions
diff --git a/web/yacco2/o2linker/Makefile b/web/yacco2/o2linker/Makefile
new file mode 100644
index 0000000000..8cec4c5caa
--- /dev/null
+++ b/web/yacco2/o2linker/Makefile
@@ -0,0 +1,86 @@
+## -*- Makefile -*-
+##
+## User: root
+## Time: Apr 17, 2007 4:35:39 PM
+## Makefile created by Sun Studio.
+##
+## This file is generated automatically.
+##
+
+#### Compiler and tool definitions shared by all build targets #####
+CCC = CC
+CXX = CC
+BASICOPTS = -fast -xtarget=opteron -m64 -mt #-xa
+CCFLAGS = $(BASICOPTS) -I'/yacco2/o2linker' -I'/yacco2/compiler/grammars' -I'/yacco2/library/grammars' -I'/yacco2/library'
+CXXFLAGS = $(BASICOPTS)
+CCADMIN = CCadmin -clean
+
+LDLIBS_o2 = -L '/yacco2/library/yacco2build/dist/Release/Sun12-Solaris-x86' -l yacco2 \
+-L '/yacco2/compiler/grammars/o2grammarsbuild/dist/Release/Sun12-Solaris-x86' -l yacco2grammars
+# Define the target directories.
+TARGETDIR_linker=Sun-x86-Solaris
+
+all: $(TARGETDIR_linker)/o2linker
+## Target: linker
+OBJS_linker = $(TARGETDIR_linker)/o2linker.o\
+ $(TARGETDIR_linker)/common_externs.o \
+ $(TARGETDIR_linker)/yacco2_extn.o \
+ $(TARGETDIR_linker)/o2linker_defs.o \
+ $(TARGETDIR_linker)/yacco2_stbl.o
+
+# Link or archive
+$(TARGETDIR_linker)/o2linker: $(TARGETDIR_linker) $(OBJS_linker)
+ $(LINK.cc) -z muldefs -z rescan $(CCFLAGS_linker) $(CPPFLAGS_linker) -o $@ $(OBJS_linker) $(LDLIBS_linker)
+
+
+# Compile source files into .o files
+$(TARGETDIR_linker)/common_externs.o: $(TARGETDIR_linker) common_externs.cpp
+ $(COMPILE.cc) $(CCFLAGS_linker) $(CPPFLAGS_linker) -o $@ common_externs.cpp
+$(TARGETDIR_linker)/yacco2_extn.o: $(TARGETDIR_linker) yacco2_extn.cpp
+ $(COMPILE.cc) $(CCFLAGS_linker) $(CPPFLAGS_linker) -o $@ yacco2_extn.cpp
+
+$(TARGETDIR_linker)/o2linker_defs.o: $(TARGETDIR_linker) o2linker_defs.cpp
+ $(COMPILE.cc) $(CCFLAGS_linker) $(CPPFLAGS_linker) -o $@ o2linker_defs.cpp
+
+$(TARGETDIR_linker)/o2linker.o: $(TARGETDIR_linker) o2linker.cpp
+ $(COMPILE.cc) $(CCFLAGS_linker) $(CPPFLAGS_linker) -o $@ o2linker.cpp
+
+%.cpp: %.w
+ cweave o2linker.w
+ ctangle -l +e o2linker.w
+ cweave /yacco2/compiler/stbl/yacco2_stbl.w
+ ctangle -l +e /yacco2/compiler/stbl/yacco2_stbl.w
+ cweave o2linker_externs.w
+ ctangle -l +e o2linker_externs.w
+ cweave /yacco2/externals/common_externs.w
+ cweave types.w
+ ctangle -l +e types.w
+ ctangle -l +e /yacco2/externals/common_externs.w
+ sh Makefile_Edit_cweb
+
+#### Clean target deletes all generated files ####
+clean:
+ rm -f \
+ $(TARGETDIR_linker)/o2linker \
+ $(TARGETDIR_linker)/o2linker_externs.o \
+ $(TARGETDIR_linker)/yacco2_stbl.o \
+ o2linker.cpp \
+ o2linker.h \
+ o2linker_externs.cpp \
+ o2linker_externs.h \
+ common_externs.cpp \
+ common_externs.h \
+ o2linker_defs.cpp \
+ yacco2_stbl.h
+ $(CCADMIN)
+ rm -f -r $(TARGETDIR_linker)
+
+
+# Create the target directory (if needed)
+$(TARGETDIR_linker):
+ mkdir -p $(TARGETDIR_linker)
+
+# Enable dependency checking
+.KEEP_STATE:
+.KEEP_STATE_FILE:.make.state.Sun-x86-Solaris
+
diff --git a/web/yacco2/o2linker/Makefile_Edit_cweb b/web/yacco2/o2linker/Makefile_Edit_cweb
new file mode 100644
index 0000000000..87d03ba20a
--- /dev/null
+++ b/web/yacco2/o2linker/Makefile_Edit_cweb
@@ -0,0 +1,36 @@
+# Makefile_Edit_cweb
+# clean up the ctangle and cweave droppings
+# changed cwebmac.tex to include \input eplain instead of modifying before o2linker, and o2linker.tex
+# comment out #line of cweb emits
+#
+tmp=/tmp/o2linker
+if [ ! -e "$tmp" ]
+then
+ mkdir $tmp
+fi
+#echo '\input eplain' > $tmp/eplain.txt
+#cat $tmp/eplain.txt o2linker.tex > $tmp/o2linker.tex
+#cp $tmp/o2linker.tex o2linker.tex
+#cat $tmp/eplain.txt o2externs.tex > $tmp/o2externs.tex
+#cp $tmp/yacco2extn.tex yacco2extn.tex
+#cat $tmp/eplain.txt yacco2stbl.tex > $tmp/yacco2stbl.tex
+#cp $tmp/yacco2stbl.tex yacco2stbl.tex
+
+sed_cmd1="'-e s;^#line;//line;'"
+sed_cmd2="'-e s/^;$//'"
+
+for i in o2linker o2linker_externs common_externs o2linker_defs # comment out line reference macros
+do
+ j=$i.cpp
+ echo "correcting cweb file: $j"
+ eval "sed $sed_cmd1 $sed_cmd2 < $j > $tmp/$j"
+ cp $tmp/$j $j
+done
+for i in o2linker o2linker_externs common_externs extndefs # comment out line reference macros of gened headers
+do
+ j=$i.h
+ echo "correcting cweb header file: $j"
+ eval "sed $sed_cmd1 $sed_cmd2 < $j > $tmp/$j"
+ cp $tmp/$j $j
+done
+rm -fr $tmp \ No newline at end of file
diff --git a/web/yacco2/o2linker/bugs.w b/web/yacco2/o2linker/bugs.w
new file mode 100644
index 0000000000..5070d81db0
--- /dev/null
+++ b/web/yacco2/o2linker/bugs.w
@@ -0,0 +1,173 @@
+@q bugs.w@>
+@q% Copyright Dave Bone 1998 - 2015@>
+@q% /*@>
+@q% This Source Code Form is subject to the terms of the Mozilla Public@>
+@q% License, v. 2.0. If a copy of the MPL was not distributed with this@>
+@q% file, You can obtain one at http://mozilla.org/MPL/2.0/.@>
+@q% */@>
+@** Bugs --- ugh. Do i make them? Sure do!
+They have all the makings of Darwinism with sloppiness due
+to work overload and not enough self evaluation ... Forget the platitudes Dude. Hey it's Dave.
+The testsuite raised 3 basic programming misconceptions that should enlighten
+u the reader in your use of Yacco2.\fbreak
+\ptindent{1) posting of errors within a thread versus a standalone grammar}
+\ptindent{2) off by xxx in error token co-ordinates}
+\ptindent{3) refining of lookahead expression for common prefix recognition}
+
+@ Posting of errors within a grammar.\fbreak
+There are 2 ways to post an error within a grammar:\fbreak
+\ptindent{1) |ADD_TOKEN_TO_ERROR_QUEUE| macro or parser's |add_token_to_error_queue| procedure}
+\ptindent{2) |RSVP| macro to post the error or parser's |add_token_to_producer| procedure}
+The |ADD_TOKEN_TO_ERROR_QUEUE| route should be used only within a standalone grammar. Why?
+Due to parallelism (nondeterminism), threads can misfire but the overall parsing is fine because
+some thread will accept its parse or the calling grammar that set things in motion also
+uses the conditional parsing features of shifting over reduce.
+
+Putting an error token into the |accept queue| via |RSVP| allows
+ the calling grammar to discriminate
+by arbitration as to what token to accept.
+Then within the grammar's subrule that handles the error token,
+the syntax-directed code would post the accepted error
+as an error and possbily shutdown the parse by parser's |set_stop_parse(true)| routine.
+This allows the grammar writer more flexibitity in error handling.
+
+So the moral of this story is ``know your parsing run context''
+when posting of errors. So where's my mistake?
+I used the |RSVP| facility within a standalone grammar.
+This just shunts the error token into the output
+token queue instead of the error queue.
+
+@ Off by xxx in error token co-ordinates.\fbreak
+When posting an error, the newly created error token needs to be associated with
+the source file position. So how is this accomplished?
+Typically one uses a previous token with established co-ordinates to
+set the error token's co-ordinates via the parser's |set_rc| routine.
+
+So why the off by xxx syndrone? What co-ordinate do u associate an error with when the grammar's
+subrule uses the wild card facility ${\vert+\vert}$ to catch an error.
+Is it the |current_token| routine?
+Not really.
+Depending on the syntax-directed code context,
+this can be the lookahead token after the shift operation.
+That is, it is one past the currently shifted token on the parse stack
+ represented symbolicly by ${\vert+\vert}$.
+So use the appropriate |Sub_rule_xxx.p1__| parameter in the syntax-directed procedure
+to reference the stacked token where xxx is the
+subrule number of this subrule. |p1__| is the first component of the
+subrule's right-hand-side expression. If there are
+other components that are to be referenced, |px__| will
+have the appropriate component number replacing x.
+
+There are other facilities open to the grammar writer like the |start_token| routine
+that provides the starting token passed to the thread for parsing for co-ordinate references.
+One can also store token references within the grammar rules as parsing takes place
+so that a ``roll your own'' fiddling within contexts can be programmed: To each their own.
+
+@ Refining of lookahead expression for keyword recognition.\fbreak
+I describe this problem using a concrete example but the problem is generic
+when there are competing threads that can have common prefixes.
+If a keyword is ``emitfile'' then should it accept ``emitfilex'' when the balance ``x'' follows?
+No it should not. This is the common prefix problem where the lookahead boundary to accept or
+abort the parse was wrongly programmed.
+As theads can fine tune their lookahead expression by the grammar's
+ ``parallel-la-boundary'' statement,
+the correction is to properly program this expression.
+See the |yacco2_linker_keywords.lex| grammar for the proper lookahead expression to abort such
+a parse.
+
+@ Take 2: Teaching the teacher --- why off by xxx in error co-ordinates?.\fbreak
+In testing linker's grammars, the following came up.
+What co-ordinate does one associate with an error token when
+the ``eog'' token produces the error? Remember, the meta-terminals like eog, ${\vert.\vert}$,
+${\vert+\vert}$ have no co-ordinates associated with them as they are shared
+across all token containers.
+
+Quick review of co-ordinates: There are 4 parts to a token's co-ordinates:\fbreak
+\ptindent{1) a file number kept by Yacco2 giving the filename source of token}
+\ptindent{2) line number within the file}
+\ptindent{3) character position on the line}
+\ptindent{4) character position within the physical file returned by the I/O routine}
+Points 1 -- 3 are used for now to print out errors.
+
+Well I had to check the source code of |set_rc| procedure.
+It was programmed properly and had comments to boot describing the problem.
+|set_rc| marches back thru the token container looking for a
+token having physical co-ordinates. Call the number of moves thru the container
+the displacement. This displacement is
+summed with the character position of the referenced token
+to point to a spot on the source line.
+The other co-ordinate attributes are just copied.
+Depending on the token's length in display characters,
+the displacement
+will be xxx moves to the right of the referenced token's co-ordinates.
+This is why the error token graphic ${\uparrow}$ is offset within the error message displaying
+against the source line and character spot.
+Depending on the length of the token in display characters,
+the offset could be within the interior of the token or to the right of it.
+This offset shows that a potential overflow
+was prevented when the ``eog'' token halts the parse.
+Have a look at testsuite's ``no end-T-alphabet keyword''
+or the last test ''end-list-of-transitive-threads keyword not present '' illustrating
+this type of situation.
+
+What about the other meta-terminals?
+This is a rool-your-own-laddie. Grab whatever context u want to associate the
+co-ordinates against the error token. In the case of the ${\vert.\vert}$, the meta-epsilon
+token, u can use the |current_token()| as its co-ordinate context.
+
+Well go tell it to the Yacco2 parse library. See |set_rc| writeup.
+The moral of this tidbit? A user manual must be written. I know but this will
+be my next venture.\fbreak
+4 May 2005.
+
+@ Missed associating the root node thread to its called threads' terminals.\fbreak
+This shows how the forest and the trees (pun intended) got blurred. The scoping of
+a screen just does not allow one to view well
+a general perspective: batteries not required
+nor a camel to carry paper and a caf\'e au lait.
+
+Now the 2 errors:\fbreak
+The |visit_graph| reserved the right amount of space but I mistakenly
+thought that the container's size procedure
+gave the number of elements reserved --- nope.
+So the |visit_graph|'s check on visited became true immediately.
+
+2nd mistake had a compound logic error: the root node thread was not associated
+with the called threads' first sets ---
+which is the raison d'\^etre for all this recursion.
+The more subtle error was checking in the global terminal's set
+for the called thread existance.
+If it was present, the root node thread was bypassed in checking whether
+it should be entered into the global terminal set.
+Boy sometimes you're dump Dave --- spelling correct at the time: haha.
+
+This error should have been caught in the test suites.
+It requires a proper set of faked grammars to test out transitive closure:
+i.e., what about nested calling grammars?, various flavors of epsilon:
+a complete pass thru grammar, ${\vert.\vert}$ to boundary detection, etc.
+
+Plain and simple I was procastinating as real work on other things is building.
+The scaffolding for these other suites requires a bit more thought and much more effort.
+Ahhh self analysis watching the watched watching --- I leave this to Freud
+but it still cost 3 hours of time lost to ferret out these bloopers.
+
+Okay I'm crafting more test suites to cruise-control these esoteric conditions.
+It demonstrates the requirement of
+well calibrated test suites as a necessary dimension to programming
+along with comments as in literate programming, and pre / post constraint declarations
+within code to catch realtime strange-ites.
+Without these tested dimensions, what assurances or confidence does one have to
+ say that the code is correct? Not much but hand wavings and hot ...
+ Let's hear it for QA and its exercising regime to come out and strut itself.\fbreak
+ 11 May 2005.
+
+@ Dynamic reserve space for |Visit_graph|.\fbreak
+The |std::vector<char> Visit_graph();|
+was originally calculating the number of threads before
+reserving space via ``reserve(xxx)'' procedure.
+This is a simple way to associate a visited node for my recursive graph walks:
+stop those revisits.
+Somehow this space was getting reallocated and destroying my trees.
+So out damm dynamics and in with static array no template please...\fbreak
+Nov. 2007\fbreak
+
diff --git a/web/yacco2/o2linker/common_externs.cpp b/web/yacco2/o2linker/common_externs.cpp
new file mode 100644
index 0000000000..6c2bf5ca10
--- /dev/null
+++ b/web/yacco2/o2linker/common_externs.cpp
@@ -0,0 +1,379 @@
+/*7:*/
+//line 87 "/usr/local/yacco2/externals/common_externs.w"
+
+/*6:*/
+//line 84 "/usr/local/yacco2/externals/common_externs.w"
+
+#include "common_externs.h"
+/*:6*/
+//line 88 "/usr/local/yacco2/externals/common_externs.w"
+
+/*8:*/
+//line 93 "/usr/local/yacco2/externals/common_externs.w"
+
+
+
+/*:8*//*10:*/
+//line 116 "/usr/local/yacco2/externals/common_externs.w"
+
+extern
+void GET_CMD_LINE
+(int argc,char*argv[],const char*Holding,yacco2::TOKEN_GAGGLE&Errors)
+{
+using namespace std;
+using namespace NS_yacco2_err_symbols;
+using namespace yacco2;
+ofstream ofile;
+ofile.open(Holding,ios_base::out|ios::trunc);
+if(!ofile){
+CAbs_lr1_sym*sym= new Err_bad_filename(Holding);
+sym->set_external_file_id(1);
+sym->set_line_no(1);
+sym->set_pos_in_line(1);
+Errors.push_back(*sym);
+return;
+}
+if(argc==1){
+char cmd_line[Max_buf_size];
+cout<<"Please enter Command line to process: ";
+cin.get(cmd_line,Max_buf_size,'\n');
+ofile<<cmd_line;
+ofile.close();
+return;
+}
+for(int x= 1;x<argc;++x){
+ofile<<argv[x]<<' ';
+}
+ofile.close();
+return;
+}
+
+/*:10*//*11:*/
+//line 167 "/usr/local/yacco2/externals/common_externs.w"
+
+extern
+void
+DUMP_ERROR_QUEUE(yacco2::TOKEN_GAGGLE&Errors)
+{
+using namespace NS_yacco2_k_symbols;
+using namespace yacco2;
+Errors.push_back(*yacco2::PTR_LR1_eog__);
+Errors.push_back(*yacco2::PTR_LR1_eog__);
+using namespace NS_o2_err_hdlr;
+Co2_err_hdlr fsm;
+Parser pass_errors(fsm,&Errors,0);
+pass_errors.parse();
+yacco2::Parallel_threads_shutdown(pass_errors);
+
+}
+
+/*:11*//*12:*/
+//line 185 "/usr/local/yacco2/externals/common_externs.w"
+
+extern const char*DATE_AND_TIME(){
+static std::string dt;
+if(dt.empty()){
+time_t theTime= time(0);
+char*cTime= ctime(&theTime);
+dt+= cTime;
+int n= dt.find('\n');
+dt[n]= ' ';
+}
+return dt.c_str();
+}
+
+/*:12*//*13:*/
+//line 199 "/usr/local/yacco2/externals/common_externs.w"
+
+extern
+void
+XLATE_SYMBOLS_FOR_cweave(const char*Sym_to_xlate,char*Xlated_sym){
+Xlated_sym[0]= (char)0;
+int lll= strlen(Sym_to_xlate);
+int app_ptr= 0;
+for(int x= 0;x<lll;++x,--app_ptr){
+switch(Sym_to_xlate[x]){
+case'{':{
+int sz= sizeof("\\BRACEOPEN{}");
+strncpy(&Xlated_sym[app_ptr],"\\BRACEOPEN{}",sz);
+app_ptr+= sz;
+continue;
+}
+case'}':{
+int sz= sizeof("\\BRACECLOSE{}");
+strncpy(&Xlated_sym[app_ptr],"\\BRACECLOSE{}",sz);
+app_ptr+= sz;
+continue;
+}
+case'<':{
+int sz= sizeof("\\LTsign{}");
+strncpy(&Xlated_sym[app_ptr],"\\LTsign{}",sz);
+app_ptr+= sz;
+continue;
+}
+case'>':{
+int sz= sizeof("\\GTsign{}");
+strncpy(&Xlated_sym[app_ptr],"\\GTsign{}",sz);
+app_ptr+= sz;
+continue;
+}
+case'@':{
+int sz= sizeof("\\ATsign{}");
+strncpy(&Xlated_sym[app_ptr],"\\ATsign{}",sz);
+app_ptr+= sz;
+continue;
+}
+case'|':{
+if(x+2<lll){
+if(Sym_to_xlate[x+2]!='|'){
+int sz= sizeof("\\Verticalbar ");
+strncpy(&Xlated_sym[app_ptr],"\\Verticalbar ",sz);
+app_ptr+= sz;
+continue;
+}
+}else{
+int sz= sizeof("\\Verticalbar ");
+strncpy(&Xlated_sym[app_ptr],"\\Verticalbar ",sz);
+app_ptr+= sz;
+continue;
+}
+switch(Sym_to_xlate[x+1]){
+case'+':{
+int sz= sizeof("\\ALLshift{}");
+strncpy(&Xlated_sym[app_ptr],"\\ALLshift{}",sz);
+app_ptr+= sz;
+x+= 2;
+continue;
+}
+case'.':{
+int sz= sizeof("\\INVshift{}");
+strncpy(&Xlated_sym[app_ptr],"\\INVshift{}",sz);
+app_ptr+= sz;
+x+= 2;
+continue;
+}
+case'?':{
+int sz= sizeof("\\QUEshift{}");
+strncpy(&Xlated_sym[app_ptr],"\\QUEshift{}",sz);
+app_ptr+= sz;
+x+= 2;
+continue;
+}
+case'|':{
+int sz= sizeof("\\PARshift{}");
+strncpy(&Xlated_sym[app_ptr],"\\PARshift{}",sz);
+app_ptr+= sz;
+x+= 2;
+continue;
+}
+case'r':{
+int sz= sizeof("\\REDshift{}");
+strncpy(&Xlated_sym[app_ptr],"\\REDshift{}",sz);
+app_ptr+= sz;
+x+= 2;
+continue;
+}
+case'p':{
+int sz= sizeof("\\PROCshift{}");
+strncpy(&Xlated_sym[app_ptr],"\\PROCshift{}",sz);
+app_ptr+= sz;
+x+= 2;
+continue;
+}
+case't':{
+int sz= sizeof("\\TRAshift{}");
+strncpy(&Xlated_sym[app_ptr],"\\TRAshift{}",sz);
+app_ptr+= sz;
+x+= 2;
+continue;
+}
+default:{
+int sz= sizeof("\\Verticalbar{}");
+strncpy(&Xlated_sym[app_ptr],"\\Verticalbar{}",sz);
+app_ptr+= sz;
+continue;
+}
+}
+}
+case'+':{
+int sz= sizeof("+");
+strncpy(&Xlated_sym[app_ptr],"+",sz);
+app_ptr+= sz;
+continue;
+}
+case'-':{
+int sz= sizeof("-");
+strncpy(&Xlated_sym[app_ptr],"-",sz);
+app_ptr+= sz;
+continue;
+}
+case'*':{
+int sz= sizeof("\\ASTERICsign{}");
+strncpy(&Xlated_sym[app_ptr],"\\ASTERICsign{}",sz);
+app_ptr+= sz;
+continue;
+}
+case'#':{
+int sz= sizeof("\\NOsign ");
+strncpy(&Xlated_sym[app_ptr],"\\NOsign ",sz);
+app_ptr+= sz;
+continue;
+}
+case'&':{
+int sz= sizeof("\\AMPERsign{}");
+strncpy(&Xlated_sym[app_ptr],"\\AMPERsign{}",sz);
+app_ptr+= sz;
+continue;
+}
+case'%':{
+int sz= sizeof("\\PERCENTsign{}");
+strncpy(&Xlated_sym[app_ptr],"\\PERCENTsign{}",sz);
+app_ptr+= sz;
+continue;
+}
+case'$':{
+int sz= sizeof("\\DOLLARsign{}");
+strncpy(&Xlated_sym[app_ptr],"\\DOLLARsign{}",sz);
+app_ptr+= sz;
+continue;
+}
+case'\\':{
+if(lll==1){
+int sz= sizeof("\\BKSLASHsign{}");
+strncpy(&Xlated_sym[app_ptr],"\\BKSLASHsign{}",sz);
+app_ptr+= sz;
+continue;
+}
+switch(Sym_to_xlate[x+1]){
+case'\\':{
+if(lll==2){
+int sz= sizeof("\\BKSLASHsign{}");
+strncpy(&Xlated_sym[app_ptr],"\\BKSLASHsign{}",sz);
+app_ptr+= sz;
+++x;
+continue;
+}
+int sz= sizeof("\\");
+strcat(Xlated_sym,"\\");
+app_ptr+= sz;
+++x;
+continue;
+}
+case'"':{
+int sz= sizeof("\\DBLQUOTEsign{}");
+strncpy(&Xlated_sym[app_ptr],"\\DBLQUOTEsign{}",sz);
+app_ptr+= sz;
+++x;
+continue;
+}
+case'\'':{
+int sz= sizeof("\\RTQUOTEsign{}");
+strncpy(&Xlated_sym[app_ptr],"\\RTQUOTEsign{}",sz);
+app_ptr+= sz;
+++x;
+continue;
+}
+case'n':{
+int sz= sizeof("\n");
+strncpy(&Xlated_sym[app_ptr],"\n",sz);
+app_ptr+= sz;
+++x;
+continue;
+}
+case't':{
+int sz= sizeof("\t");
+strncpy(&Xlated_sym[app_ptr],"\t",sz);
+app_ptr+= sz;
+++x;
+continue;
+}
+case'r':{
+int sz= sizeof("\r");
+strncpy(&Xlated_sym[app_ptr],"\r",sz);
+app_ptr+= sz;
+++x;
+continue;
+}
+case'v':{
+int sz= sizeof("\v");
+strncpy(&Xlated_sym[app_ptr],"\v",sz);
+app_ptr+= sz;
+++x;
+continue;
+}
+case'b':{
+int sz= sizeof("\b");
+strncpy(&Xlated_sym[app_ptr],"\b",sz);
+app_ptr+= sz;
+++x;
+continue;
+}
+case'f':{
+int sz= sizeof("\f");
+strncpy(&Xlated_sym[app_ptr],"\f",sz);
+app_ptr+= sz;
+++x;
+continue;
+}
+case'a':{
+int sz= sizeof("\a");
+strncpy(&Xlated_sym[app_ptr],"\a",sz);
+app_ptr+= sz;
+++x;
+continue;
+}
+case'?':{
+int sz= sizeof("\?");
+strncpy(&Xlated_sym[app_ptr],"\?",sz);
+app_ptr+= sz;
+++x;
+continue;
+}
+default:{
+int sz= sizeof("\\");
+strncpy(&Xlated_sym[app_ptr],"\\",sz);
+app_ptr+= sz-1;
+strncpy(&Xlated_sym[app_ptr],&Sym_to_xlate[x+1],1);
+++app_ptr;
+strncpy(&Xlated_sym[app_ptr],"",1);
+++x;
+++app_ptr;
+continue;
+}
+}
+}
+case'^':{
+int sz= sizeof("\\UPARROWsign{}");
+strncpy(&Xlated_sym[app_ptr],"\\UPARROWsign{}",sz);
+app_ptr+= sz;
+continue;
+}
+case'~':{
+int sz= sizeof("\\TILDE{}");
+strncpy(&Xlated_sym[app_ptr],"\\TILDE{}",sz);
+app_ptr+= sz;
+continue;
+}
+case'_':{
+int sz= sizeof("\\_");
+strncpy(&Xlated_sym[app_ptr],"\\_",sz);
+app_ptr+= sz;
+continue;
+}
+default:{
+strncpy(&Xlated_sym[app_ptr],&Sym_to_xlate[x],1);
+++app_ptr;
+strncpy(&Xlated_sym[app_ptr],"",1);
+++app_ptr;
+continue;
+}
+}
+}
+}
+
+/*:13*/
+//line 89 "/usr/local/yacco2/externals/common_externs.w"
+
+
+
+/*:7*/
diff --git a/web/yacco2/o2linker/common_externs.h b/web/yacco2/o2linker/common_externs.h
new file mode 100644
index 0000000000..2a6f913943
--- /dev/null
+++ b/web/yacco2/o2linker/common_externs.h
@@ -0,0 +1,28 @@
+/*4:*/
+//line 63 "/usr/local/yacco2/externals/common_externs.w"
+
+#ifndef common_extern_
+#define common_extern_ 1
+
+//line 66 "/usr/local/yacco2/externals/common_externs.w"
+
+/*5:*/
+//line 71 "/usr/local/yacco2/externals/common_externs.w"
+
+#include "globals.h"
+#include "/usr/local/yacco2/compiler/o2/o2_types.h"
+#include "o2_lcl_opts.h"
+#include "o2_lcl_opt.h"
+#include "o2_err_hdlr.h"
+extern
+void GET_CMD_LINE(int argc,char*argv[]
+,const char*File,yacco2::TOKEN_GAGGLE&Errors);
+extern
+void DUMP_ERROR_QUEUE(yacco2::TOKEN_GAGGLE&Errors);
+extern const char*DATE_AND_TIME();
+/*:5*/
+//line 67 "/usr/local/yacco2/externals/common_externs.w"
+
+#endif
+
+/*:4*/
diff --git a/web/yacco2/o2linker/globals.h b/web/yacco2/o2linker/globals.h
new file mode 100644
index 0000000000..e087b874b8
--- /dev/null
+++ b/web/yacco2/o2linker/globals.h
@@ -0,0 +1,26 @@
+/*1:*/
+#line 13 "./o2linker_types.w"
+
+
+
+#ifndef globals_h__
+#define globals_h__ 1
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+
+#include "yacco2.h"
+#include "yacco2_T_enumeration.h"
+#include "yacco2_err_symbols.h"
+#include "yacco2_characters.h"
+#include "yacco2_k_symbols.h"
+#include "yacco2_terminals.h"
+using namespace std;
+using namespace NS_yacco2_T_enum;
+using namespace NS_yacco2_k_symbols;
+using namespace NS_yacco2_terminals;
+using namespace yacco2;
+#endif
+
+/*:1*/
diff --git a/web/yacco2/o2linker/includes.w b/web/yacco2/o2linker/includes.w
new file mode 100644
index 0000000000..8236682a1f
--- /dev/null
+++ b/web/yacco2/o2linker/includes.w
@@ -0,0 +1,42 @@
+@q file: includes.w@>
+@q% Copyright Dave Bone 1998 - 2015@>
+@q% /*@>
+@q% This Source Code Form is subject to the terms of the Mozilla Public@>
+@q% License, v. 2.0. If a copy of the MPL was not distributed with this@>
+@q% file, You can obtain one at http://mozilla.org/MPL/2.0/.@>
+@q% */@>
+@*2 Include files.
+To start things off, these are the Standard Template Library (STL) containers
+needed by Linker, Yacco2's parse library definitions, and the specific
+grammar definitions needed by Linker.
+@<Include files@>=
+#include "globals.h"
+#include "yacco2_stbl.h"
+using namespace yacco2_stbl;
+#include "o2linker_externs.h"
+#include "link_cleanser.h"
+#include "t_alphabet.h"
+#include "fsc_file.h"
+
+
+@ Include \Olinker header.
+@<io2@>=
+#include "o2linker.h"
+
+@*2 Create header file for \O2{}linker environment.\fbreak
+Note, the ``include search'' directories for the c++ compiler has to be supplied
+to the compiler environment used. This must include \Yacco2's library.
+@(o2linker.h@>=
+@h
+#ifndef o2linker__
+#define o2linker__ 1
+@<Include files@>;
+ @<External rtns and variables@>;
+#endif
+
+@*2 \O2{}linker implementation.\fbreak
+Start the code output to |o2linker.cpp|
+by appending its include file.
+@(o2linker.cpp@>=
+@<io2@>;
+@<accrue linker code@>;
diff --git a/web/yacco2/o2linker/intro.w b/web/yacco2/o2linker/intro.w
new file mode 100644
index 0000000000..ddd81631c5
--- /dev/null
+++ b/web/yacco2/o2linker/intro.w
@@ -0,0 +1,394 @@
+@q file: intro.w@>
+@q% Copyright Dave Bone 1998 - 2015@>
+@q% /*@>
+@q% This Source Code Form is subject to the terms of the Mozilla Public@>
+@q% License, v. 2.0. If a copy of the MPL was not distributed with this@>
+@q% file, You can obtain one at http://mozilla.org/MPL/2.0/.@>
+@q% */@>
+@** Summary of Yacco2's Linker --- threads and their bit maps.\fbreak
+\Olinker produces ``thread bit maps'' for each terminal
+ and a global table of to-run threads, and
+a linker document describing all the processed grammars
+extracted from their grammar's ``fsm-comments''
+ and their called threads.
+Standalone grammars: monolithic y, are also traversed to
+add their thread booty to the global bit maps.
+As Linker is a companion program of Yacco2, please see Yacco2's documentation
+for appropriate development of data structures that are germain to both.
+
+Linker receives its input either interactively or as a command line.
+The file to compile contains a list of grammar first set control files
+generated by Yacco2.
+Each grammar's ``first set'' file generated by Yacco2 uses a naming convention
+of the ``thread name'' supplied by the grammar's |fsm-filename| with an extension of ``fsc''
+indicating a ``first set'' control file.
+At present, Linker's inputted file is handcrafted by the grammar writer
+due to Yacco2 not having a generation database of compiled grammars.
+The below diagram shows \O2{}Linker's manufacturing assembly line for the
+``bit maps'' object file within an Unix context where the ``ld'' linker program
+resolves the globals described in the following section.
+The ``pdf'' generated document provides an overview description of all the grammars in use.
+``CC'' is the c++ compiler on my Sun Solaris work station.
+\fbreak
+\fbreak
+\convertMPtoPDF{"/usr/local/yacco2/diagrams/o2linker_overview.1"}{1}{1}
+\fbreak
+\fbreak
+The ``O2linker\_doc.pdf'' document provides an index of all grammars compiled
+with comments about their claim-to-fame.
+It is a nice overview document of your language software
+when debugging or just getting a feel for all those defined grammars.
+It demarks the threaded grammars from their monolithic brethren.
+
+@*2 Globals --- those unresolved static variables used by Yacco2's library.\fbreak
+The following variables are made global for Yacco2's parse library usuage and
+placed within |yacco2| namespace:\fbreak
+\ptindent{1) |THDS_STABLE__| - vector of threads for the running}
+\ptindent{2) |T_ARRAY_HAVING_THD_IDS__| - terminals' thread sets}
+\ptindent{3) |BIT_MAPS_FOR_SALE__| - block of 32 bit words for bit map manufacture}
+\ptindent{4) |BIT_MAP_IDX__| - index used to dispense bit maps}
+\ptindent{5) |TOTAL_NO_BIT_WORDS__| - total number of words for sale}
+
+To speed things up and not be involved
+with the |malloc| issues of new / delete, |BIT_MAPS_FOR_SALE__|
+is a constant size of bit map words.
+Its size is controlled by the |TOTAL_NO_BIT_WORDS| macro and indicated at
+run-time by the |TOTAL_NO_BIT_WORDS__| global.
+Why not use c++ template containers?
+Depending on the context, they are not very efficient and in some cases they are not robust
+depending on whose compiler one uses.
+So ``roll your own'' is my mode of operandi. At least I can bark at myself
+instead of dealing with charades of good-citizenship a la Microsoft
+and their bug reporting - fixes: their stated policy of 24 hours response after submitting
+the bug report and now its 2 weeks and I'm still waiting for an acknowledgement.
+Have you seen their latest website
+for bug reporting? No direct button to send the report, only the platitude of
+how wastefull it is at their cost to deal with bug reports so make sure that you review their
+stated digest of bugs before submitting.
+How does democracy come into play when bugs are bugs: Fix them!
+Ranking bugs by developer votes is just (you substitute one of the
+following adjectives: stupid, senseless, witless, dull, brainless, weak-brained,
+muddle-headed, beef-witted, unentertaining). You get my sentiment.
+
+Each global will be developed in their appropriate sections.
+
+
+@*2 Some definitions within Linker's context.\fbreak
+What is a ``first set'' within the linker's context?\fbreak
+It is the terminals within the Start state configuration
+(aka ``Closure only'' state) of an automaton.
+There is some subtlety to this statement as an epsilon rule (empty right-hand-side),
+special terminals ${\vert+\vert}$ and ${\vert.\vert}$,
+ and threads being called
+from within the ``Closure only'' state require special treatment as their
+terminals are outside of this state.
+These situations require going into other state configurations to determine the
+terminals.
+Possibly an epsilon rule and special terminals but definitely
+threads presents a more difficult problem as the
+grammar being parsed does not have access to the called thread's first set.
+Why? A called thread is another grammar requiring compilation.
+This is why Linker is required to post process all grammars in a global context to
+calculate the first sets for grammars calling threads out of their ``Closure only'' state.
+\fbreak
+\fbreak
+Why first sets anyway?\fbreak
+Originally this was not programmed. I wanted to prove my concepts first before
+optimizing for speed.
+Reality demands that a good idea be also practical.
+What good is parsing with threads when they are orders of magnitude slower
+than the current crop of parsing paradigns?
+So to overcome slowness, first sets provide the potential of whether a thread
+should run.
+How? If the current token to be parsed is in the first set of the thread then
+launch it from the running parse context.
+This optimization prevents false thread starts.
+\fbreak
+\fbreak
+Why the name \Olinker instead of for example ``first setter'' or jet?\fbreak
+I checked to the current name of tools required to
+prepare a program as an executable.
+In a sense Linker in my mind's eye was a concept that
+brought together the loose ends of the grammars and made it ready to parse.
+First setter is also appropriate.
+\fbreak
+\fbreak
+How are first sets generated?\fbreak
+The basic problem solved by Linker is the following:
+within a grammar, threads can be called.
+If threads called are within the Start state of a grammar,
+ the grammar's
+first set now has a dependence on another thread's first set.
+Of course this call sequence is transitive: thread A can call thread B can call thread C.
+Both threads B and C can have a call thread dependency within their
+first sets.
+It is this thread dependency that the Linker resolves by applying the
+transitive closure operation across a graph of thread nodes
+to outcome the explicit first set of terminals per dependent thread.
+The output from Linker is a global vector of threads to be run, and their
+global first set bit maps optimized against all terminals. That is, what
+threads can be run by this current terminal.
+
+
+@*2 Overview of \Olinker's generated components.\fbreak
+Threads are just your normal procedures that get launched
+under the guidance of the threading facility native to the operating system
+instead of being called directly.
+Yacco2's parse library documentation goes into the detail between each
+run-time advantages threads versus procedure calls: After experimenting with a stop watch,
+the winner is the threads approach due to c++'s overhead of object birth-run-destructor cycle.
+
+Now the issue becomes ``how to determine and provide a thread id?'' that
+can be referenced globally and locally.
+Why the distinction between global and local contexts?
+Local contexts are the individual grammars that can reference other threads
+who are defined globally outside of its domain.
+As raised before, Linker's raison-d'\^etre is post-processing in a global context all the
+compiled threads.
+As the \o2 compiler / compiler processes the grammar in a local parsing context, references
+to threads within the grammar must be delayed thru indirection in its generated tables.
+This indirection comes from objects whose references are globally defined
+via the ``extern'' c(++) language facility and resolved by the appropriate language linker.
+
+An entente between the global and local contexts was signed in 1066 whereby the
+ charter of thread rights
+ defined the |Thread_entry| structure.
+Each |Thread_entry| uses a naming convention
+of: Ixxx where xxx is the thread name without its namespace drawn from the grammar.
+\o2 generates references to these thread entries whilst Linker creates the
+actual thread entry entities.
+The |Thread_entry| contains a pointer to the literal thread name
+used in \o2's tracings,
+the address to its called procedure, and its thread id that
+is a key to appropriate tables and thread maps.
+Thread ids are positive whole numbers starting from 0.
+The thread names are sorted in ascending sequence. Each thread's id is its
+relative position within this sorted sequence.
+
+
+@*2 Thread bit maps.\fbreak
+To give speed and economy of space, 32 bit words are used whereby
+each bit within a word represents the presence or absence of a specific thread.
+Why 32 bit words? This falls nicely in the current crop of CPUs.
+As 64 bit envy becomes mainstream, the number of bits per word can be changed
+by |cweb|'s macro facility.
+The mapping of a thread id into its bit map, uses modulo 32 on the thread id.
+The quotient indicates which word to access and the remainder indicates
+which specific bit within the word represents the thread.
+Due to the open number of threads being defined,
+the total number of words making up a thread map is
+specific to each parsing environment. For example, the
+current number of threads for \o2 is under 50. So, each thread map
+is 2 words long.
+
+Use of bit maps allows set processing with its operators like intersection to take place.
+Due to other optimizations to be discussed later, the number of words per bit map
+for \Yacco2's parsing library
+is calculated at runtime from the global |THDS_STABLE__| structure
+ that carries the total number of threads being
+supported for the current parse environment.
+The globals |TOTAL_NO_OF_BIT_WORDS__|, |BIT_MAPS_FOR_SALE__|, and |BIT_MAP_IDX__| are used to
+manufacture bit maps.
+Why not manufacture bit maps at time of \o2 running?
+Neither the local grammar or \o2 has any notion to what its or other threads ids are.
+Also, I did not want to impose on the grammar writer an unique thread id assignment within each
+grammar nor an approximation of the total number of threads being developed.
+
+Now, \Yacco2's runtime library has a just-in-time thread map manufacture process.
+Each parsing thread's state keeps a list of threads to possibly run but list processing
+to launch threads is too slow.
+So when a parsing thread arrives at a state configuration needing thread bit maps,
+\Yacco2's library will
+manufacture it using the globals |BIT_MAPS_FOR_SALE__| and |BIT_MAP_IDX__|.
+|BIT_MAP_IDX__| controls the current index into |BIT_MAPS_FOR_SALE__| that houses
+the words for the bit maps.
+This newly minted thread map is now available throughout the balance of the parsing
+of the thread by storing the map address in the state configuration.
+
+The below diagram depicts a partial bit map configuration:\fbreak
+\fbreak
+\fbreak
+\convertMPtoPDF{"/usr/local/yacco2/diagrams/linker.2"}{1}{1}
+\fbreak
+\fbreak
+The word 0 above is in ``big endian'' sequence composed of 4 bytes: byte 0 is the first
+covering
+the most significant bit 31 thru to bit 24 while
+byte 3 contains the least significant bit 0
+where its bits range from 7 thru to 0.
+It illustrates threads 31, 23, 15, 7, and 0 as
+being available for the running as their bits are ``turned on'' represented
+by ``1''.
+Word 1 would have the
+thread id range of 63 thru to 32. Each thread id in a word
+ is just a replay of the modulo: Q is the word map no * 32 + the R the remainder
+ indicating the specific bit from 0..31.
+
+
+@*2 Linker's languages.\fbreak
+There are 3 separate languages to be parsed by Linker:\fbreak
+\ptindent{1) Terminal alphabet --- literal names of each terminal}
+\ptindent{2) Each grammar's first set control file generated by \o2 --- xxx.fsc}
+\ptindent{3) Linker's input control file}
+
+These languages are simplistic but requires proper
+parsing that, of course, will use Yacco2's parse library.
+
+@*2 Terminal alphabet.\fbreak
+This is your terminal vocabulary defined by the 4 classes of terminals:
+LR constants, raw characters, errors, and ``user created'' terminals.
+Its content provides the literal description per terminal used for annotated
+comments in the emitted file. Their input order is also their enumeration.
+This file is outputted by \o2 when one requests the terminals to be compiled
+using one of its gen options: ``-t'' for user terminals or ``-err'' for errors.
+It uses the filename provided by the grammar's T-enumeration's file-name construct
+with a ``fsc'' extension (aka first set control).
+For the \o2 grammars, it looks like this:\fbreak
+\listing{"/usr/local/yacco2/diagrams/intro1.txt"}
+\fbreak
+The outputted vocabulary file is ``|yacco2_T_enumeration.fsc|'' from this above example.
+
+The language uses a bracketing construct
+``T-alphabet'' ... ``end-T-alphabet''
+to contain the list of terminals by their name defined by the grammar's ``terminals'' constructs:
+Lrk, raw characters, errors, and terminals.
+Below is an example:\fbreak
+\listing{"/usr/local/yacco2/diagrams/intro2.txt"}
+
+@*3 Terminal enumeration.\fbreak
+As the inputted terminals are by name, to be more efficient,
+an enumeration scheme is used whereby each terminal's relative position within this list
+starting at 0 becomes their assigned number working
+ out along the positive whole numbers.
+From the example above, the |LR1_questionable_shift_operator| terminal is assigned 0,
+|LR1_eog| terminal is assigned 1 and so on.
+In \Yacco2's documentation you'll find
+``how it applies'' this enumeration to the shifting and reducing sets
+within the automaton tables.
+The storage for these sets favors space economy over speed.
+
+@*3 First set declarations.\fbreak
+\o2 outputs per grammar their first set files having
+a file naming convention of the grammar name with an extension of ``fsc''.
+Below is ``subrule\_def.fsc'' first set control file
+outputted by the subrule\_def.lex grammar.\fbreak
+\let\setuplistinghook = \linenumberedlisting
+\listing{"/usr/local/yacco2/diagrams/intro3.txt"}
+
+This is a summary of what was found within the grammar.
+I included line numbers each delimited by a ``:'' to the left of the language's
+individual source lines as reference points for the
+discussion that follows.
+Lines 5 -- 11 above are the prelude declarations of the compiled grammar.
+The 2 items of interest within the prelude are the keywords ``transitive'' and ``monolithic''.
+Both use a boolean declaration of ``y'' or ``n''.
+The ``transitive'' keyword indicates whether this grammar needs transitive processing.
+The ``monolithic'' keyword indicates whether the grammar is stand alone
+or threaded.
+
+The 3 components following the prelude indicate the intent by their names.
+Lines 12 -- 13 houses the ``list-of-native-first-set-terminals'' component:
+the grammar's explicitly used terminals within its first set where there this
+example has none.
+The ``list-of-transitive-threads'' component: lines 14 -- 16
+indicates the directly called threads from their first set.
+This list is recursively called
+by assessing their called threads's ``fsc'' files:
+the transitive adjective is a memory jog to recursion.
+Please see |first_set_for_threads| grammar on how the
+thread's first set is calculated as
+there is a subtle difference caused by the \INVshift
+in its first set calculation versus
+the regular first set calcaluation of a rule or lr state.
+Lines 17 -- 28 is a cross reference
+list of used threads throughout the grammar
+ and not just the first set.
+Lines 29 -- 30 is the extracted fsm-comments from the grammar.
+It is used in generating the Linker's document indexing
+all the grammars with their comments, and
+their called thread graph with highlighting of nested grammars.
+
+@*2 Linker's control language.\fbreak
+There is not much to this control file.
+It provides the terminal vocabulary file,
+the file to output by Linker,
+a preamble that allows the grammar writer to insert code
+ahead of the ``to be emitted'' code, and finally
+the list of grammars' ``fsc'' files to process.
+Here is a sample of a handcrafted Linker control file drawn from the \o2
+parsing environment.\fbreak
+\let\setuplistinghook = \relax
+\listing{"/usr/local/yacco2/diagrams/intro4.txt"}
+\fbreak
+Basicly, Linker builds a graph by grammar and does its transitive moves to
+produce concrete first sets for each unresolved grammar or thread.
+To improve performance, a global thread map per terminal will be created
+indicating the potential threads that can be run.
+
+@*2 Catalogue of Linker's files.\fbreak
+Linker's Input files to |cweb|:\fbreak
+\ptindent{1) |o2linker.w| --- master Linker file that starts things off}
+\ptindent{2) |intro.w| --- inroduction }
+\ptindent{3) |prog.w| --- linker cweb code }
+\ptindent{4) |o2linker_externs.w| --- external procedures }
+\ptindent{5) |pms.w| --- running comments of life}
+\ptindent{6) |bugs.w| --- yep i do them}
+\ptindent{7) |testsuites.w| --- self proof of code}
+\ptindent{8) |sampleoutput.w|}
+\ptindent{9) |types.w| --- provides a way around burping output formats}
+\ptindent{10) |includes.w| --- C++ include code}
+\ptindent{11) /usr/local/yacco2/externals/common\_defs.w --- external procedures }
+\ptindent{12) |o2linker_defs.w| --- external procedures }
+
+|cweb| generated files:\fbreak
+\ptindent{1) |o2linker.h| --- linker definitions}
+\ptindent{2) |o2linker.cpp| --- linker program}
+\ptindent{3) |xxx.cpp| --- first sets for grammars provided by the input file}
+
+\Yacco2 library memorabilia:\fbreak
+\ptindent{1) yacco2 --- library namespace}
+\ptindent{2) ``\Whereyacco2/library'' --- \yacco2's library directory}
+\ptindent{3) ${< yacco2.h >}$ --- Yacco2's library header file}
+\ptindent{4) ``\Whereyacco2/library/lib/xxxx'' - xxxx is the Debug or Release of the object library}
+\ptindent{5) ``yacco2build.a'' - static \yacco2's library}
+
+Dependency files from other Yacco2 sub-systems:\fbreak
+\ptindent{|yacco2.h| - basic definitions used by Yacco2}
+\ptindent{|yacco2_T_enumeration.h| - terminal enumeration for \Yacco2's terminal grammar alphabet}
+\ptindent{|yacco2_err_symbols.h| - error terminal definitions from \Yacco2's grammar alphabet}
+\ptindent{|yacco2_characters.h| - raw character definitions from \Yacco2's grammar alphabet}
+\ptindent{|yacco2_k_symbols.h| - constant terminal definitions from \Yacco2's grammar alphabet}
+\ptindent{|yacco2_terminals.h| - regular terminal definitions from \Yacco2's grammar alphabet}
+\ptindent{|*.h| - assorted grammar definitions from \Yacco2 to parse}
+\ptindent{|o2linker_externs.h| - external support routines common for \olinker}
+
+Dictionaries\fbreak
+\ptindent{|T_DICTIONARY| --- terminals}
+\ptindent{|GRAMMAR_DICTIONARY|}
+\ptindent{|YACCO2_STBL| --- symbol table}
+\ptindent{|USED_THREADS_LIST|}
+\ptindent{|THREAD_ID_FIRST_SET|}
+\ptindent{|T_THREAD_ID_LIST|}
+Grammars\fbreak
+\ptindent{|T_alphabet.lex|}
+\ptindent{|linker_pass3.lex| --- control file parser }
+\ptindent{|link_cleanser.lex| --- lexical grammar stripping off comments etc}
+\ptindent{|fsc_file.lex| --- syntactic grammar of fsc file}
+Document\fbreak
+\ptindent{|o2linker_doc.w| --- overall index describing the grammars processed: cweave / pdftex}
+
+@*2 Global macro definitions.\fbreak
+@d SPECULATIVE_NO_BIT_WORDS 20
+@d LR1_QUESTIONABLE_SHIFT_OPERATOR 0
+@d LR1_EOG 1
+@d LR1_EOLR 2
+@d LR1_PARALLEL_OPERATOR 3
+@d LR1_REDUCE_OPERATOR 4
+@d LR1_PROCEDURE_CALL_OPERATOR 7
+@d LR1_INVISIBLE_SHIFT_OPERATOR 5
+@d LR1_ALL_SHIFT_OPERATOR 6
+@d LR1_FSET_TRANSIENCE_OPERATOR 7
+@d SMALL_BUFFER_4K 1024*4
+@d BITS_PER_WORD 32
+@d TOTAL_NO_BIT_WORDS 1024*2*100
+
diff --git a/web/yacco2/o2linker/makefile_APPLE b/web/yacco2/o2linker/makefile_APPLE
new file mode 100644
index 0000000000..f2a08e73a2
--- /dev/null
+++ b/web/yacco2/o2linker/makefile_APPLE
@@ -0,0 +1,110 @@
+# File: makefile_APPLE
+# Why: Creates the o2linker companion to o2 compiler /compiler
+# Library placement:
+# Rlse: /usr/local/yacco2/bin/o2linker
+# Dbg: /usr/local/yacco2/bin/o2linker_debug
+# Genw: Create the pdf file: yacco2/docs
+# Generate the *.cpp files from cweb
+#
+# How to run: U must choose the label to execute: Rlse, Dbg
+# Rlse --- gen the fast version of o2linker with no debug support
+# Dbg --- gen the debug version of o2liner_debug
+# Genw --- gen the pdf document and the cpp code
+# from cweb see www.tug.org for details on obtaining code
+# for the literate programming environment aka CWEB
+# and please join Tug. It is a marvelous FOSS
+# Note: U do not need to use Genw as *.cpp and pdf
+# document are included in the ``yacco2'' package
+#
+# ---> Know where the stdc++ library resides and adjust the STDCC_dir variable
+#
+# Example: gen the debug version compiler/compiler linker: o2linker_debug using GNU make
+# cd /usr/local//yacco2/compiler/grammars
+# make Dbg -f makefile_APPLE
+# Example: gen document and cpp sub/programs
+# make Genw -f makefile_APPLE
+#
+
+O2 := /usr/local/yacco2
+#CC := /opt/local/bin/gcc-mp-4.9
+CC := clang++ #g++
+#LD := /opt/local/bin/ld
+LD := ld #apple linker
+LD_PARMS := -arch x86_64 #-macosx_version_min 10.9 -no_compact_unwind
+
+02_target_dir :=
+ifeq ($(MAKECMDGOALS),Rlse)
+O2_target_dir := Release
+Prg := o2linker
+Compile_opts := -c -pthread -arch x86_64 #-frepo -fno-implicit-templates -fno-rtti
+else
+O2_target_dir := Debug
+Prg := o2linker_debug
+Compile_opts := -c -g -pthread -arch x86_64
+endif
+
+###
+# Set up directories
+###
+Base_o2 := $(O2)
+O2_bin := $(Base_o2)/bin
+O2_eternals := $(Base_o2)/externals
+O2_docs := $(Base_o2)/docs
+O2_lib := $(Base_o2)/library
+O2_lib_grms := $(Base_o2)/library/grammars
+O2_cc_grms := $(Base_o2)/compiler/grammars
+O2_cc := $(Base_o2)/compiler/o2
+O2_includes := -I'$(O2_cc_grms)' -I'$(O2_lib)' -I'$(O2_lib_grms)'
+O2_req_libraries := -lyacco2 -lo2grammars
+O2_lib_directories := -L$(O2_cc_grms)/lib/$(O2_target_dir) -L$(O2_lib)/lib/$(O2_target_dir)
+CC_lib := c++
+
+##CC_lib := stdc++ #gnu c++
+LD_PARMS := -arch x86_64 -macosx_version_min 10.9 #-stack_size 0x2000000 -no_compact_unwind
+
+#STDCC_dir := -L/usr/llvm-gcc-4.2/lib/gcc/i686-apple-darwin11/4.2.1/
+##STDCC_dir := -L/opt/local/lib/gcc49/ #gnu c++
+STDCC_dir := -L/usr/lib/
+
+###
+# Compile, link, and move O2 into bin account
+###
+Rlse: YYY Move_o2linker
+Dbg: YYY Move_o2linker
+YYY:
+ $(CC) $(Compile_opts) $(O2_includes) o2linker.cpp -o $(Prg).o
+ $(CC) $(Compile_opts) $(O2_includes) common_externs.cpp -o common_externs.o
+ $(CC) $(Compile_opts) $(O2_includes) o2linker_externs.cpp -o o2linker_externs.o
+ $(CC) $(Compile_opts) $(O2_includes) o2linker_defs.cpp -o o2linker_defs.o
+ $(LD) $(LD_PARMS) -o $(Prg) $(STDCC_dir) $(O2_lib_directories) $(O2_req_libraries) -l$(CC_lib) -lpthread o2linker_externs.o o2linker_defs.o common_externs.o $(Prg).o
+
+Move_o2linker:
+ mv $(Prg) $(O2_bin)
+ rm *.o
+
+Genw:
+ cweave o2linker_types
+ pdftex o2linker_types
+ mv o2linker_types.pdf $(O2_docs)
+ cweave o2linker
+ pdftex o2linker
+ mv o2linker.pdf $(O2_docs)
+ cweave $(O2_eternals)/common_externs
+ pdftex common_externs
+ mv common_externs.pdf $(O2_docs)
+ cweave o2linker_externs
+ pdftex o2linker_externs
+ mv o2linker_externs.pdf $(O2_docs)
+ ctangle -l +e $(O2_eternals)/common_externs
+ ctangle -l +e o2linker_externs
+ ctangle -l +e o2linker_defs
+ ctangle -l +e o2linker
+ ctangle -l +e o2linker_types
+ sh Makefile_Edit_cweb
+ rm *.idx
+ rm *.scn
+ rm *.toc
+ rm *.tex
+ rm *.log
+ rm *.c
+
diff --git a/web/yacco2/o2linker/makefile_GNU b/web/yacco2/o2linker/makefile_GNU
new file mode 100644
index 0000000000..12067d8a97
--- /dev/null
+++ b/web/yacco2/o2linker/makefile_GNU
@@ -0,0 +1,82 @@
+# File: makefile_GNU
+# Why: Creates the o2linker companion to o2 compiler /compiler
+# Library placement:
+# Rlse: /usr/local/yacco2/bin/o2linker
+# Dbg: /usr/local/yacco2/bin/o2linker_dbg
+# Genw: for the pdf file: yacco2/docs
+# for the *.cpp files
+#
+# How to run: U must choose the label to execute: Rlse, Dbg
+# Rlse --- gen the fast version of library with no debug support
+# Dbg --- gen the debug version of library
+# Genw --- gen the pdf document and the cpp code
+# from cweb see www.tug.org for details on obtaining code
+# for the literate programming environment aka CWEB
+# and please join Tug. It is a marvalous FOSS
+# Note: U do not need to use Genw as *.cpp and pdf
+# document are included in the ``yacco2'' package
+#
+# Example: gen the debug version of the library
+# cd /usr/local/yacco2/compiler/grammars
+# make Dbg -f Solaris_makefile
+#
+CC := g++
+
+02_target_dir :=
+ifeq ($(MAKECMDGOALS),Rlse)
+O2_target_dir := Release
+else
+O2_target_dir := Debug
+endif
+
+Base_yacco2 := $(O2)
+O2_bin := $(Base_yacco2)/bin
+O2_eternals := $(Base_yacco2)/externals
+O2_docs := $(Base_yacco2)/docs
+O2_lib := $(Base_yacco2)/library
+O2_lib_grms := $(Base_yacco2)/library/grammars
+O2_cc_grms := $(Base_yacco2)/compiler/grammars
+O2_cc := $(Base_yacco2)/compiler/o2
+O2_includes := -I'$(O2_cc)' -I'$(O2_cc_grms)' -I'$(O2_lib)' -I'$(O2_lib_grms)'
+O2_req_libraries := -lyacco2 -lo2grammars
+O2_lib_directories := -L$(O2_cc_grms)/lib/$(O2_target_dir) -L$(O2_lib)/lib/$(O2_target_dir)
+
+###
+# Set up c++ compiler and ld linker options
+###
+Rlse: Compile_opts := -c -O3 -pthread
+Dbg: Compile_opts := -c -g -pthread
+Link_opts := -Wl,-z -Wl,muldefs -Wl,-Ur #$(O2_lib_directories)
+Multi_rd_libs := -static-libgcc -Wl,--start-group -lyacco2 -lo2grammars -Wl,--end-group -lpthread
+
+###
+# Compile, link, and move O2linker into bin account
+###
+Rlse: YYY Move_rlse_o2linker
+Dbg: YYY Move_dbg_o2linker
+YYY:
+ $(CC) -v $(Compile_opts) o2linker.cpp -o o2linker.o $(O2_includes)
+ $(CC) -v $(Compile_opts) common_externs.cpp -o common_externs.o $(O2_includes)
+ $(CC) -v $(Compile_opts) o2linker_externs.cpp -o o2linker_externs.o $(O2_includes)
+ $(CC) -v $(Compile_opts) o2linker_defs.cpp -o o2linker_defs.o $(O2_includes)
+ ld '-o' 'o2linker' '-shared-libgcc' '-mtune=generic'\
+ --eh-frame-hdr -m elf_i386 --hash-style=both -dynamic-linker\
+ /lib/ld-linux.so.2 -o o2linker -z relro /usr/lib/gcc/i486-linux-gnu/4.3.2/../../../../lib/crt1.o\
+ /usr/lib/gcc/i486-linux-gnu/4.3.2/../../../../lib/crti.o /usr/lib/gcc/i486-linux-gnu/4.3.2/crtbegin.o\
+ -L/usr/lib/gcc/i486-linux-gnu/4.3.2 -L/usr/lib/gcc/i486-linux-gnu/4.3.2\
+ -L/usr/lib/gcc/i486-linux-gnu/4.3.2/../../../../lib -L/lib/../lib -L/usr/lib/../lib\
+ -L/usr/lib/gcc/i486-linux-gnu/4.3.2/../../..\
+ $(O2_lib_directories) o2linker_externs.o o2linker_defs.o common_externs.o o2linker.o\
+ --whole-archive -lyacco2 --no-whole-archive -start-group -lo2grammars --end-group -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc\
+ -lpthread /usr/lib/gcc/i486-linux-gnu/4.3.2/crtend.o\
+ /usr/lib/gcc/i486-linux-gnu/4.3.2/../../../../lib/crtn.o
+
+Move_rlse_o2linker:
+ mv o2linker $(O2_bin)
+ rm *.o
+Move_dbg_o2linker:
+ mv o2linker o2linker_dbg
+ mv o2linker_dbg $(O2_bin)
+ rm o2linker
+ rm *.o
+
diff --git a/web/yacco2/o2linker/makefile_SOLARIS b/web/yacco2/o2linker/makefile_SOLARIS
new file mode 100644
index 0000000000..bfe9324679
--- /dev/null
+++ b/web/yacco2/o2linker/makefile_SOLARIS
@@ -0,0 +1,141 @@
+# File: makefile_SOLARIS
+# Why: Creates the o2linker compaion to o2 compiler /compiler
+# Library placement:
+# Rlse: /usr/local/yacco2/bin/o2linker
+# Dbg: /usr/local/yacco2/bin/o2linker_debug
+# Genw: for the pdf file: yacco2/docs
+# for the *.cpp files
+#
+# How to run: U must choose the label to execute: Rlse, Dbg
+# Rlse --- gen the fast version of library with no debug support
+# Dbg --- gen the debug version of library
+# Genw --- gen the pdf document and the cpp code
+# from cweb see www.tug.org for details on obtaining code
+# for the literate programming environment aka CWEB
+# and please join Tug. It is a marvalous FOSS
+# Note: U do not need to use Genw as *.cpp and pdf
+# document are included in the ``yacco2'' package
+# Notice: Some possible construction to be done
+# 1) Adjust base_dir variable if the ``yacco2'' package is moved elsewhere.
+# For example, if u installed the ``yacco2'' package in /opt/yacco2
+# Set the base_dir variable in this file to: base_dir = /opt/
+# The trailing / must be there or ugly things will happen.
+#
+# 2) Make sure u know where the ``ranlib'' utility resides on your system
+# If it's already defined in your ``bash'' ``PATH'' varable then
+# just space out the below ``RANLIB'' variable
+# RANLIB =
+# or set it to point to its residence as what this file has done
+#
+# Example: gen the debug version of the library
+# cd /usr/local/yacco2/compiler/grammars
+# make Dbg -f Solaris_makefile
+#
+
+o2_eternals :=$(O2)/externals/
+o2_docs := $(O2)/docs/
+o2_lib = $(O2)/library/
+o2_lib_grms := $(O2)/library/grammars/
+o2_grms := $(O2)/compiler/grammars/
+o2linker := $(O2)/o2linker/
+O2_includes := -I'$(o2)' -I'$(o2_grms)' -I'$(o2_lib)' -I'$(o2_lib_grms)'
+o2_req_libraries := -lyacco2 -lo2grammars
+
+files_to_cc := \
+$(o2linker)o2linker_defs.cpp \
+$(o2linker)common_externs.cpp \
+$(o2linker)o2linker_externs.cpp \
+$(o2linker)o2linker.cpp
+files_to_o := $(files_to_cc:.cpp=.o)
+
+Rlse: BASICOPTS := -c -fast -m64 -lpthread
+Rlse: Bld_BASICOPTS := -m64 -lpthread -xs
+Rlse: o2_lib_directories := -L $(o2_grms)lib/Release/ -L $(o2_lib)lib/Release/
+
+Dbg: BASICOPTS := -c -m64 -lpthread -g
+Dbg: Bld_BASICOPTS := -m64 -lpthread -xs -g
+Dbg: o2_lib_directories := -L $(o2_grms)lib/Debug/ -L $(o2_lib)lib/Debug/
+
+Rlse: Compile Rlse_o2
+Rlse := BASICOPTS = -c -fast -m64 -mt -lpthread
+Rlse := Bld_BASICOPTS = -fast -m64 -mt -lpthread
+Rlse := o2_lib_directories = -L $(o2_grms)lib/Release/ -L $(o2_lib)lib/Release/
+Rlse_o2:
+ mv o2linker $(base_dir)yacco2/bin/o2linker
+ rm -f *.o
+
+Dbg: $(files_to_o) Dbg_o2
+Dbg := BASICOPTS = -c -m64 -mt -lpthread -xs -g
+Dbg := Bld_BASICOPTS = -m64 -mt -lpthread -xs -g
+Dbg := o2_lib_directories = -L $(o2_grms)lib/Debug/ -L $(o2_lib)lib/Debug/
+Dbg_o2:
+ mv o2linker $(base_dir)yacco2/bin/o2linker_debug
+ rm -f *.o
+
+Compile: $(files_to_o)
+$(o2linker)common_externs.o: $(o2)common_externs.cpp
+ CC $(BASICOPTS) $(O2_includes) $(o2)common_externs.cpp -o $@
+$(o2linker)o2linker_externs.o: $(o2)o2linker_externs.cpp
+ CC $(BASICOPTS) $(O2_includes) $(o2)o2linker_externs.cpp -o $@
+$(o2linker)o2linker_defs.o: $(o2)o2linker_defs.cpp
+ CC $(BASICOPTS) $(O2_includes) $(o2)o2linker_defs.cpp -o $@
+$(o2linker)o2linker.o: $(o2)o2linker.cpp
+ CC $(Bld_BASICOPTS) $(O2_includes) $(o2)o2linker.cpp -o o2linker \
+$(o2linker)o2linker_defs.o $(o2)common_externs.o $(o2)o2linker_externs.o \
+$(o2_lib_directories) $(o2_req_libraries)
+Genw:
+ cweave types.w
+ ctangle -l +e types.w
+ pdftex types
+ mv types.pdf $(o2_docs)
+ cweave $(o2_eternals)common_externs.w
+ ctangle -l +e $(o2_eternals)common_externs.w
+ pdftex common_externs
+ mv common_externs.pdf $(o2_docs)
+ cweave o2linker_externs.w
+ ctangle -l +e o2linker_externs.w
+ pdftex o2linker_externs
+ pdftops o2linker_externs.pdf
+ mv o2linker_externs.pdf $(o2_docs)
+ mv o2linker_externs.ps $(o2_docs)
+ cweave o2linker.w
+ ctangle -l +e o2linker.w
+ sh Makefile_Edit_cweb
+ pdftex o2linker
+ pdftops o2linker.pdf
+ mv o2linker.pdf $(o2_docs)
+ mv o2linker.ps $(o2_docs)
+ cweave o2linker_doc.w
+ pdftex o2linker_doc
+ pdftops o2linker_doc.pdf
+ mv o2linker_doc.pdf $(o2_docs)
+ mv o2linker_doc.ps $(o2_docs)
+ rm types.idx
+ rm types.scn
+ rm types.toc
+ rm types.tex
+ rm types.log
+ rm types.c
+ rm common_externs.idx
+ rm common_externs.scn
+ rm common_externs.toc
+ rm common_externs.tex
+ rm common_externs.log
+ rm common_externs.c
+ rm o2linker_externs.idx
+ rm o2linker_externs.scn
+ rm o2linker_externs.toc
+ rm o2linker_externs.tex
+ rm o2linker_externs.log
+ rm o2linker_externs.c
+ rm o2linker.idx
+ rm o2linker.scn
+ rm o2linker.toc
+ rm o2linker.tex
+ rm o2linker.log
+ rm o2linker.c
+ rm o2linker_doc.idx
+ rm o2linker_doc.scn
+ rm o2linker_doc.toc
+ rm o2linker_doc.tex
+ rm o2linker_doc.log
diff --git a/web/yacco2/o2linker/o2linker.cpp b/web/yacco2/o2linker/o2linker.cpp
new file mode 100644
index 0000000000..d1c689d8e4
--- /dev/null
+++ b/web/yacco2/o2linker/o2linker.cpp
@@ -0,0 +1,1132 @@
+/*89:*/
+//line 40 "/usr/local/yacco2/o2linker/includes.w"
+
+/*87:*/
+//line 23 "/usr/local/yacco2/o2linker/includes.w"
+
+#include "o2linker.h"
+
+/*:87*/
+//line 41 "/usr/local/yacco2/o2linker/includes.w"
+
+/*20:*/
+//line 125 "/usr/local/yacco2/o2linker/prog.w"
+
+void load_linkkw_into_tbl(yacco2::CAbs_lr1_sym*Kw){
+using namespace yacco2_stbl;
+T_sym_tbl_report_card report_card;
+KCHARP kwkey= Kw->id();
+if(*kwkey=='#')++kwkey;
+kw_in_stbl*kw= new kw_in_stbl(Kw);
+add_sym_to_stbl(report_card,*kwkey,*kw,table_entry::defed,table_entry::keyword);
+kw->stbl_idx(report_card.pos_);
+}
+
+void load_linkkws_into_tbl()
+{
+cout<<"Load linker's keywords "<<endl;
+load_linkkw_into_tbl(new T_transitive);
+load_linkkw_into_tbl(new T_grammar_name);
+load_linkkw_into_tbl(new T_name_space);
+load_linkkw_into_tbl(new T_thread_name);
+load_linkkw_into_tbl(new T_fsm_comments);
+load_linkkw_into_tbl(new T_monolithic);
+load_linkkw_into_tbl(new T_file_name);
+load_linkkw_into_tbl(new T_no_of_T);
+load_linkkw_into_tbl(new T_list_of_native_first_set_terminals);
+load_linkkw_into_tbl(new T_end_list_of_native_first_set_terminals);
+load_linkkw_into_tbl(new T_list_of_transitive_threads);
+load_linkkw_into_tbl(new T_end_list_of_transitive_threads);
+load_linkkw_into_tbl(new T_list_of_used_threads);
+load_linkkw_into_tbl(new T_end_list_of_used_threads);
+load_linkkw_into_tbl(new T_T_alphabet);
+load_linkkw_into_tbl(new T_end_T_alphabet);
+load_linkkw_into_tbl(new T_file_of_T_alphabet);
+load_linkkw_into_tbl(new T_emitfile);
+load_linkkw_into_tbl(new T_preamble);
+load_linkkw_into_tbl(new T_end_preamble);
+}
+
+
+/*:20*//*22:*/
+//line 208 "/usr/local/yacco2/o2linker/prog.w"
+
+bool sort_threads_criteria(const table_entry*P1,const table_entry*P2){
+th_in_stbl*th_tbl1= (th_in_stbl*)P1->symbol_;
+th_in_stbl*th_tbl2= (th_in_stbl*)P2->symbol_;
+thread_attributes*p1= th_tbl1->thread_in_stbl();
+thread_attributes*p2= th_tbl2->thread_in_stbl();
+int len_a= p1->thread_name_->c_string()->size();
+int len_b= p2->thread_name_->c_string()->size();
+string ucase_a;
+for(int x= 0;x<len_a;++x){
+ucase_a+= toupper((*p1->thread_name_->c_string())[x]);
+}
+string ucase_b;
+for(int x= 0;x<len_b;++x){
+ucase_b+= toupper((*p2->thread_name_->c_string())[x]);
+}
+if(len_a<len_b){
+for(int x= len_a+1;x<=len_b;++x)ucase_a+= ' ';
+}else{
+for(int x= len_b+1;x<=len_a;++x)ucase_b+= ' ';
+}
+int result;
+if(p1->monolithic_=='n'){
+if(p2->monolithic_=='n'){
+result= strcmp(ucase_a.c_str(),ucase_b.c_str());
+if(result<0)return true;
+return false;
+}
+return true;
+}
+if(p2->monolithic_=='n'){
+return false;
+}
+
+int len_fqna= p1->thread_name_->c_string()->size();
+int len_fqnb= p2->thread_name_->c_string()->size();
+string ucase_fqna;
+for(int x= 0;x<len_fqna;++x){
+ucase_fqna+= toupper((*p1->thread_name_->c_string())[x]);
+}
+string ucase_fqnb;
+for(int x= 0;x<len_fqnb;++x){
+ucase_fqnb+= toupper((*p2->thread_name_->c_string())[x]);
+}
+if(len_fqna<len_fqnb){
+for(int x= len_fqna+1;x<=len_fqnb;++x)ucase_fqna+= ' ';
+}else{
+for(int x= len_fqnb+1;x<=len_fqna;++x)ucase_fqnb+= ' ';
+}
+result= strcmp(ucase_fqna.c_str(),ucase_fqnb.c_str());
+if(result<0)return true;
+return false;
+}
+
+/*:22*//*33:*/
+//line 434 "/usr/local/yacco2/o2linker/prog.w"
+
+void crt_fset_of_thread
+(thread_attributes&Visited_th
+,int Root_thread_id,thread_attributes&Root_thread){
+if(Visit_graph[Visited_th.th_enum_]=='y')return;
+Visit_graph[Visited_th.th_enum_]= 'y';
+/*31:*/
+//line 396 "/usr/local/yacco2/o2linker/prog.w"
+
+std::vector<int> ::iterator fi= Visited_th.list_of_Ts_.begin();
+std::vector<int> ::iterator fie= Visited_th.list_of_Ts_.end();
+for(;fi!=fie;++fi){
+int t_enum= *fi;
+if(t_enum==LR1_ALL_SHIFT_OPERATOR){
+/*29:*/
+//line 332 "/usr/local/yacco2/o2linker/prog.w"
+
+INT_SET_ITER_type t_listi= Root_thread.fs_.find(LR1_EOLR);
+if(t_listi==Root_thread.fs_.end()){
+Root_thread.fs_.insert(LR1_EOLR);
+}
+
+int no_of_T= T_DICTIONARY.size();
+for(int x= 0;x<no_of_T;++x){
+switch(x){
+case LR1_QUESTIONABLE_SHIFT_OPERATOR:break;
+case LR1_EOG:break;
+case LR1_EOLR:continue;
+case LR1_PARALLEL_OPERATOR:continue;
+case LR1_REDUCE_OPERATOR:continue;
+case LR1_INVISIBLE_SHIFT_OPERATOR:continue;
+case LR1_ALL_SHIFT_OPERATOR:continue;
+case LR1_FSET_TRANSIENCE_OPERATOR:continue;
+default:break;
+}
+if(Visited_th.monolithic_=='n'){
+INT_SET_type&th_list= T_THREAD_ID_LIST[x];
+if(th_list.find(Visited_th.th_enum_)==th_list.end()){
+th_list.insert(Visited_th.th_enum_);
+}
+if(th_list.find(Root_thread_id)==th_list.end()){
+th_list.insert(Root_thread_id);
+}
+}
+}
+
+/*:29*/
+//line 402 "/usr/local/yacco2/o2linker/prog.w"
+
+}
+/*30:*/
+//line 369 "/usr/local/yacco2/o2linker/prog.w"
+
+INT_SET_ITER_type t_listi= Root_thread.fs_.find(t_enum);
+if(t_listi==Root_thread.fs_.end()){
+Root_thread.fs_.insert(t_enum);
+}
+if(Visited_th.monolithic_=='n'){
+INT_SET_type&th_list= T_THREAD_ID_LIST[t_enum];
+if(th_list.find(Visited_th.th_enum_)==th_list.end()){
+th_list.insert(Visited_th.th_enum_);
+}
+if(th_list.find(Root_thread_id)==th_list.end()){
+th_list.insert(Root_thread_id);
+}
+}
+
+/*:30*/
+//line 404 "/usr/local/yacco2/o2linker/prog.w"
+
+}
+
+/*:31*/
+//line 440 "/usr/local/yacco2/o2linker/prog.w"
+
+/*32:*/
+//line 409 "/usr/local/yacco2/o2linker/prog.w"
+
+std::vector<thread_attributes*> ::iterator li= Visited_th.list_of_transitive_threads_.begin();
+std::vector<thread_attributes*> ::iterator lie= Visited_th.list_of_transitive_threads_.end();
+for(;li!=lie;++li){
+thread_attributes*th_att= *li;
+lrclog<<"------->process called thread's list thd: "
+<<th_att->thread_name_->c_string()->c_str()
+<<" for root thd id: "<<Root_thread_id
+<<endl;
+crt_fset_of_thread(*th_att,Root_thread_id,Root_thread);
+}
+
+/*:32*/
+//line 441 "/usr/local/yacco2/o2linker/prog.w"
+
+}
+
+/*:33*//*38:*/
+//line 503 "/usr/local/yacco2/o2linker/prog.w"
+
+void walk_called_thread_list(std::vector<thread_attributes*> &Thd_list,AST*Mother_thd_t){
+if(Thd_list.begin()==Thd_list.end())return;
+std::vector<thread_attributes*> ::iterator li= Thd_list.begin();
+std::vector<thread_attributes*> ::iterator lie= Thd_list.end();
+for(;li!=lie;++li){
+thread_attributes*th_att= *li;
+if(Visit_graph[th_att->th_enum_]=='y')continue;
+Visit_graph[th_att->th_enum_]= 'y';
+AST*called_t= new AST(*th_att);
+AST::add_child_at_end(*Mother_thd_t,*called_t);
+walk_called_thread_list(th_att->list_of_transitive_threads_,called_t);
+}
+}
+
+/*:38*//*39:*/
+//line 519 "/usr/local/yacco2/o2linker/prog.w"
+
+void crt_called_thread_graph(thread_attributes&Visited_th){
+if(Visit_graph[Visited_th.th_enum_]=='y')return;
+Visit_graph[Visited_th.th_enum_]= 'y';
+AST*mother_thd_t= new AST(Visited_th);
+Visited_th.called_thread_graph_= mother_thd_t;
+walk_called_thread_list(Visited_th.list_of_transitive_threads_,mother_thd_t);
+}
+/*:39*//*40:*/
+//line 528 "/usr/local/yacco2/o2linker/prog.w"
+
+void gen_each_grammar_s_referenced_threads(){
+std::vector<table_entry*> ::iterator thi= GRAMMAR_DICTIONARY.begin();
+std::vector<table_entry*> ::iterator thie= GRAMMAR_DICTIONARY.end();
+for(;thi!=thie;++thi){
+th_in_stbl*th_tbl= (th_in_stbl*)(*thi)->symbol_;
+thread_attributes*th_att= th_tbl->thread_in_stbl();
+/*35:*/
+//line 454 "/usr/local/yacco2/o2linker/prog.w"
+
+for(int vi= 0;vi<NO_OF_THREADS;++vi){
+Visit_graph[vi]= 'n';
+}
+
+/*:35*/
+//line 535 "/usr/local/yacco2/o2linker/prog.w"
+
+crt_called_thread_graph(*th_att);
+}
+}
+/*:40*//*52:*/
+//line 773 "/usr/local/yacco2/o2linker/prog.w"
+
+void emit_no_threads(ofstream&ofile){
+ofile<<"// There are NO THREADS emitted"<<endl;
+ofile<<"void* yacco2::THDS_STABLE__ = 0;"<<endl;
+ofile<<"void* yacco2::T_ARRAY_HAVING_THD_IDS__ = 0;"<<endl;
+}
+
+/*:52*//*53:*/
+//line 781 "/usr/local/yacco2/o2linker/prog.w"
+
+void emit_cpp_preamble(ofstream&ofile,const char*OFile,const char*Preamble){
+ofile<<"//"<<endl;
+ofile<<"// File: "<<OFile<<endl;
+ofile<<"// Generated by linker.exe"<<endl;
+ofile<<"// Date and Time: "<<DATE_AND_TIME()<<endl;
+ofile<<"//"<<endl;
+ofile<<endl;
+ofile<<"// Preamble code"<<endl;
+ofile<<Preamble<<endl;
+}
+
+/*:53*//*54:*/
+//line 799 "/usr/local/yacco2/o2linker/prog.w"
+
+void emit_global_thread_include_files(ofstream&ofile){
+ofile<<"// thread include and namespace"<<std::endl;
+char a[SMALL_BUFFER_4K];
+KCHARP thread_include_ns= "#include \"%s.h\"";
+
+std::vector<table_entry*> ::iterator thi= GRAMMAR_DICTIONARY.begin();
+std::vector<table_entry*> ::iterator thie= GRAMMAR_DICTIONARY.end();
+for(;thi!=thie;++thi){
+th_in_stbl*th_tbl= (th_in_stbl*)(*thi)->symbol_;
+thread_attributes*th_att= th_tbl->thread_in_stbl();
+if(th_att->monolithic_=='y')break;
+int x= sprintf
+(a
+,thread_include_ns
+,th_att->grammar_file_name_->c_string()->c_str()
+);
+ofile.write(a,x);
+ofile<<std::endl;
+}
+}
+
+/*:54*//*55:*/
+//line 822 "/usr/local/yacco2/o2linker/prog.w"
+
+void emit_global_bit_maps(ofstream&ofile){
+ofile<<"// BIT MAPS"<<std::endl;
+ofile<<"#define TOTAL_NO_BIT_WORDS 2*1024*50"<<std::endl;
+ofile<<"int yacco2::TOTAL_NO_BIT_WORDS__(TOTAL_NO_BIT_WORDS);"<<std::endl;
+ofile<<"yacco2::ULINT bit_maps[TOTAL_NO_BIT_WORDS];"<<std::endl;
+ofile<<"void* yacco2::BIT_MAPS_FOR_SALE__ = (void*)&bit_maps;"<<std::endl;
+ofile<<"int yacco2::BIT_MAP_IDX__(0);"<<std::endl;
+}
+
+/*:55*//*56:*/
+//line 844 "/usr/local/yacco2/o2linker/prog.w"
+
+void emit_global_thread_stable(ofstream&ofile){
+ofile<<"// THREAD STABLE"<<std::endl;
+char a[BIG_BUFFER_32K];
+KCHARP thread_entry= "yacco2::Thread_entry I%s = {%s,%s,%i,%s::PROC_%s};";
+string quoted_name;
+/*57:*/
+//line 855 "/usr/local/yacco2/o2linker/prog.w"
+
+std::vector<table_entry*> ::iterator thi= GRAMMAR_DICTIONARY.begin();
+std::vector<table_entry*> ::iterator thie= GRAMMAR_DICTIONARY.end();
+for(;thi!=thie;++thi){
+th_in_stbl*th_tbl= (th_in_stbl*)(*thi)->symbol_;
+thread_attributes*th_att= th_tbl->thread_in_stbl();
+if(th_att->monolithic_=='y')break;
+quoted_name.clear();
+const char*th_name= th_att->thread_name_->c_string()->c_str();
+quoted_name+= '"';
+quoted_name+= th_name;
+quoted_name+= '"';
+
+int x= sprintf(a,thread_entry,th_name,quoted_name.c_str()
+,th_att->fully_qualified_th_name_.c_str(),th_att->th_enum_
+,th_att->name_space_name_->c_string()->c_str()
+,th_att->thread_name_->c_string()->c_str());
+ofile.write(a,x);
+ofile<<std::endl;
+}
+
+/*:57*/
+//line 850 "/usr/local/yacco2/o2linker/prog.w"
+
+/*58:*/
+//line 878 "/usr/local/yacco2/o2linker/prog.w"
+
+div_t c= div(NO_OF_THREADS,BITS_PER_WORD);
+if(c.rem!=0)++c.quot;
+NO_WORDS_FOR_BIT_MAP= c.quot;
+
+KCHARP thread_array=
+"struct thd_array_type {\n"
+" yacco2::USINT no_entries__;\n"
+" yacco2::Thread_entry* first_entry__[%i];"
+"};\n"
+"thd_array_type thd_array = {\n"
+" %i\n"
+" ,\n"
+" {\n";
+int x= sprintf(a,thread_array,NO_OF_THREADS,NO_OF_THREADS);
+
+ofile.write(a,x);
+ofile<<std::endl;
+bool first_entry(true);
+thi= GRAMMAR_DICTIONARY.begin();
+thie= GRAMMAR_DICTIONARY.end();
+KCHARP thread_entry_name= "&I%s";
+for(;thi!=thie;++thi){
+th_in_stbl*th_tbl= (th_in_stbl*)(*thi)->symbol_;
+thread_attributes*th_att= th_tbl->thread_in_stbl();
+if(th_att->monolithic_=='y')break;
+if(first_entry==true){
+first_entry= false;
+ofile<<" ";
+}else{
+ofile<<" ,";
+}
+int x= sprintf(a,thread_entry_name,th_att->thread_name_->c_string()->c_str());
+ofile.write(a,x);
+ofile<<std::endl;
+}
+ofile<<" }\n};"<<endl;
+/*59:*/
+//line 918 "/usr/local/yacco2/o2linker/prog.w"
+
+ofile<<"void* yacco2::THDS_STABLE__ = (void*)&thd_array;"<<endl;
+
+/*:59*/
+//line 915 "/usr/local/yacco2/o2linker/prog.w"
+
+
+/*:58*/
+//line 851 "/usr/local/yacco2/o2linker/prog.w"
+
+}
+
+/*:56*//*60:*/
+//line 951 "/usr/local/yacco2/o2linker/prog.w"
+
+void emit_T_fs_of_potential_threads(ofstream&ofile){
+ofile<<"// Terminal thread sets"<<std::endl;
+int no_of_T= T_DICTIONARY.size();
+char a[SMALL_BUFFER_4K];
+KCHARP T_list_to_thd_list_type=
+"struct T_%i_type{\n"
+" yacco2::ULINT first_entry__[%i];\n"
+"};\n";
+KCHARP T_list_to_thd_list_var= "T_%i_type T_%i = {// for T: %s";
+KCHARP thd_id_in_list= "//%i: %s";
+
+INT_SET_LIST_ITER_type i= T_THREAD_ID_LIST.begin();
+INT_SET_LIST_ITER_type ie= T_THREAD_ID_LIST.end();
+int terminal_id(-1);
+for(;i!=ie;++i){
+++terminal_id;
+INT_SET_type&th_list= *i;
+if(th_list.empty()==true)continue;
+int x= sprintf(a,T_list_to_thd_list_type,terminal_id,NO_WORDS_FOR_BIT_MAP);
+ofile.write(a,x);
+ofile<<std::endl;
+/*61:*/
+//line 984 "/usr/local/yacco2/o2linker/prog.w"
+
+int no_thds_ids= th_list.size();
+table_entry*t_entry= T_DICTIONARY[terminal_id];
+tth_in_stbl*t_in_stbl= (tth_in_stbl*)t_entry->symbol_;
+T_attributes*t_att= t_in_stbl->t_in_stbl();
+x= sprintf(a
+,T_list_to_thd_list_var
+,terminal_id
+,terminal_id
+,t_att->fully_qualified_T_name_.c_str()
+);
+ofile.write(a,x);
+ofile<<std::endl;
+ULINT word_map[SPECULATIVE_NO_BIT_WORDS]= {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+
+INT_SET_ITER_type j= th_list.begin();
+INT_SET_ITER_type je= th_list.end();
+
+/*62:*/
+//line 1007 "/usr/local/yacco2/o2linker/prog.w"
+
+for(;j!=je;++j){
+int th_id= *j;
+table_entry*tbl_entry= GRAMMAR_DICTIONARY[th_id];
+th_in_stbl*th_tbl= (th_in_stbl*)tbl_entry->symbol_;
+thread_attributes*th_att= th_tbl->thread_in_stbl();
+div_t bb= div(th_id,BITS_PER_WORD);
+ULINT bit_pos_value= 1<<bb.rem;
+word_map[bb.quot]|= bit_pos_value;
+int x= sprintf(a,thd_id_in_list,th_id,th_att->thread_name_->c_string()->c_str());
+ofile.write(a,x);
+ofile<<std::endl;
+}
+
+/*:62*/
+//line 1002 "/usr/local/yacco2/o2linker/prog.w"
+
+/*63:*/
+//line 1022 "/usr/local/yacco2/o2linker/prog.w"
+
+for(int dd= 1;dd<=NO_WORDS_FOR_BIT_MAP;++dd){
+if(dd==1)ofile<<" {";
+else ofile<<" ,";
+ofile<<word_map[dd-1]<<endl;
+}
+ofile<<" }"<<endl;
+ofile<<"};"<<endl;
+
+/*:63*/
+//line 1003 "/usr/local/yacco2/o2linker/prog.w"
+
+
+/*:61*/
+//line 973 "/usr/local/yacco2/o2linker/prog.w"
+
+}
+/*64:*/
+//line 1033 "/usr/local/yacco2/o2linker/prog.w"
+
+KCHARP T_array_type=
+"struct t_array_type {\n"
+" yacco2::USINT no_entries__;\n"
+" yacco2::thd_ids_having_T* first_entry__[%i];\n"
+"};";
+int x= sprintf(a,T_array_type,no_of_T);
+ofile.write(a,x);
+ofile<<std::endl;
+
+KCHARP T_array=
+"t_array_type t_array = {\n"
+" %i\n"
+" ,{";
+x= sprintf
+(a
+,T_array
+,no_of_T
+);
+ofile.write(a,x);
+ofile<<std::endl;
+
+i= T_THREAD_ID_LIST.begin();
+ie= T_THREAD_ID_LIST.end();
+/*65:*/
+//line 1063 "/usr/local/yacco2/o2linker/prog.w"
+
+bool first_item(true);
+for(int t_id= -1;i!=ie;++i){
+++t_id;
+table_entry*t_entry= T_DICTIONARY[t_id];
+tth_in_stbl*t_in_stbl= (tth_in_stbl*)t_entry->symbol_;
+T_attributes*t_att= t_in_stbl->t_in_stbl();
+INT_SET_type&th_list= *i;
+if(th_list.empty()==true){
+if(first_item==true)first_item= false;
+else ofile<<" ,";
+KCHARP T_array_entries= "%s// %s";
+int x= sprintf(a,T_array_entries,"0",t_att->fully_qualified_T_name_.c_str());
+ofile.write(a,x);
+ofile<<std::endl;
+continue;
+}else{
+if(first_item==true)first_item= false;
+else ofile<<" ,";
+KCHARP T_list_to_thd_list_var= "(yacco2::thd_ids_having_T*)&T_%i // %s";
+
+int x= sprintf(a,T_list_to_thd_list_var,t_id,t_att->fully_qualified_T_name_.c_str());
+ofile.write(a,x);
+ofile<<std::endl;
+}
+}
+
+/*:65*/
+//line 1057 "/usr/local/yacco2/o2linker/prog.w"
+
+ofile<<" }\n};"<<endl;
+ofile<<"void* yacco2::T_ARRAY_HAVING_THD_IDS__ = (void*)&t_array;"<<endl;
+
+/*:64*/
+//line 975 "/usr/local/yacco2/o2linker/prog.w"
+
+}
+
+
+/*:60*//*66:*/
+//line 1091 "/usr/local/yacco2/o2linker/prog.w"
+
+YACCO2_define_trace_variables();
+yacco2::TOKEN_GAGGLE Error_queue;
+STBL_T_ITEMS_type STBL_T_ITEMS;
+std::vector<NS_yacco2_terminals::table_entry*> GRAMMAR_DICTIONARY;
+std::map<std::string,std::vector<std::string> > USED_THREADS_LIST;
+std::vector<NS_yacco2_terminals::table_entry*> T_DICTIONARY;
+INT_SET_LIST_type T_THREAD_ID_LIST;
+
+int NO_OF_THREADS(0);
+int NO_WORDS_FOR_BIT_MAP(0);
+char Visit_graph[RESERVE_FIXED_NO_THREADS];
+extern void XLATE_SYMBOLS_FOR_cweave(const char*Sym_to_xlate,char*Xlated_sym);
+extern void PRINT_CALLED_THREAD_LIST
+(yacco2::AST*Node,std::ofstream*Ow_linker_file,int Recursion_level);
+string cntl_file_name;
+yacco2::CHAR PRT_SW('n');
+
+int main(int argc,char*argv[])
+{
+cout<<yacco2::O2linker_VERSION<<std::endl;
+using namespace yacco2;
+using namespace std;
+load_linkkws_into_tbl();
+cout<<"Get command line and parse it "<<endl;
+GET_CMD_LINE(argc,argv,Linker_holding_file,Error_queue);
+/*15:*/
+//line 34 "/usr/local/yacco2/o2linker/prog.w"
+
+if(Error_queue.empty()!=true){
+DUMP_ERROR_QUEUE(Error_queue);
+return 1;
+}
+
+/*:15*/
+//line 1117 "/usr/local/yacco2/o2linker/prog.w"
+
+LINKER_PARSE_CMD_LINE(Linker_holding_file,cntl_file_name,Error_queue);
+/*15:*/
+//line 34 "/usr/local/yacco2/o2linker/prog.w"
+
+if(Error_queue.empty()!=true){
+DUMP_ERROR_QUEUE(Error_queue);
+return 1;
+}
+
+/*:15*/
+//line 1119 "/usr/local/yacco2/o2linker/prog.w"
+
+lrclog<<yacco2::O2linker_VERSION<<std::endl;
+/*17:*/
+//line 45 "/usr/local/yacco2/o2linker/prog.w"
+
+cout<<"Parse linker control file "<<endl;
+using namespace NS_linker_pass3;
+tok_can<std::ifstream> cntl_file_tokens(cntl_file_name.c_str());
+TOKEN_GAGGLE P3_tokens;
+Clinker_pass3 linker_cntl_file_fsm;
+Parser linker_cntl_file(linker_cntl_file_fsm,&cntl_file_tokens,&P3_tokens,0,&Error_queue,0,0);
+linker_cntl_file.parse();
+/*15:*/
+//line 34 "/usr/local/yacco2/o2linker/prog.w"
+
+if(Error_queue.empty()!=true){
+DUMP_ERROR_QUEUE(Error_queue);
+return 1;
+}
+
+/*:15*/
+//line 53 "/usr/local/yacco2/o2linker/prog.w"
+
+
+/*:17*/
+//line 1121 "/usr/local/yacco2/o2linker/prog.w"
+
+/*18:*/
+//line 66 "/usr/local/yacco2/o2linker/prog.w"
+
+cout<<"Parse alphabet"<<endl;
+using namespace NS_link_cleanser;
+tok_can<std::ifstream> T_file_tokens(linker_cntl_file_fsm.t_alphabet_filename_.c_str());
+TOKEN_GAGGLE cleanser_tokens;
+Clink_cleanser cleanser_fsm;
+Parser cleanser(cleanser_fsm,&T_file_tokens,&cleanser_tokens,0,&Error_queue,0,0);
+cleanser.parse();
+
+using namespace NS_t_alphabet;
+TOKEN_GAGGLE T_tokens;
+Ct_alphabet T_fsm;
+Parser T_pass3(T_fsm,&cleanser_tokens,&T_tokens,0,&Error_queue,0,0);
+T_pass3.parse();
+/*15:*/
+//line 34 "/usr/local/yacco2/o2linker/prog.w"
+
+if(Error_queue.empty()!=true){
+DUMP_ERROR_QUEUE(Error_queue);
+return 1;
+}
+
+/*:15*/
+//line 80 "/usr/local/yacco2/o2linker/prog.w"
+
+
+/*:18*/
+//line 1122 "/usr/local/yacco2/o2linker/prog.w"
+
+/*19:*/
+//line 88 "/usr/local/yacco2/o2linker/prog.w"
+
+cout<<"Parse fsc files"<<endl;
+TOKEN_GAGGLE cleanser_fsc_tokens;
+TOKEN_GAGGLE fsc_file_output_tokens;
+std::vector<std::string> ::iterator ii= linker_cntl_file_fsm.grammars_fsc_files_.begin();
+std::vector<std::string> ::iterator iie= linker_cntl_file_fsm.grammars_fsc_files_.end();
+for(;ii!=iie;++ii){
+tok_can<std::ifstream> T_fsc_file_tokens(ii->c_str());
+Clink_cleanser cleanser_fsc;
+Parser fsc_cleanser(cleanser_fsc,&T_fsc_file_tokens
+,&cleanser_fsc_tokens,0,&Error_queue,0,0);
+fsc_cleanser.parse();
+/*15:*/
+//line 34 "/usr/local/yacco2/o2linker/prog.w"
+
+if(Error_queue.empty()!=true){
+DUMP_ERROR_QUEUE(Error_queue);
+return 1;
+}
+
+/*:15*/
+//line 100 "/usr/local/yacco2/o2linker/prog.w"
+
+
+using namespace NS_fsc_file;
+Cfsc_file fsc_file_fsm;
+Parser fsc_file_pass(fsc_file_fsm,&cleanser_fsc_tokens
+,&fsc_file_output_tokens,0,&Error_queue,0,0);
+fsc_file_pass.parse();
+/*15:*/
+//line 34 "/usr/local/yacco2/o2linker/prog.w"
+
+if(Error_queue.empty()!=true){
+DUMP_ERROR_QUEUE(Error_queue);
+return 1;
+}
+
+/*:15*/
+//line 107 "/usr/local/yacco2/o2linker/prog.w"
+
+cleanser_fsc_tokens.clear();
+fsc_file_output_tokens.clear();
+}
+/*15:*/
+//line 34 "/usr/local/yacco2/o2linker/prog.w"
+
+if(Error_queue.empty()!=true){
+DUMP_ERROR_QUEUE(Error_queue);
+return 1;
+}
+
+/*:15*/
+//line 111 "/usr/local/yacco2/o2linker/prog.w"
+
+
+/*:19*/
+//line 1123 "/usr/local/yacco2/o2linker/prog.w"
+
+/*21:*/
+//line 173 "/usr/local/yacco2/o2linker/prog.w"
+
+std::vector<table_entry*> ::iterator th_i= GRAMMAR_DICTIONARY.begin();
+std::vector<table_entry*> ::iterator th_ie= GRAMMAR_DICTIONARY.end();
+for(;th_i!=th_ie;++th_i){
+table_entry*tbl_entry= *th_i;
+
+if(tbl_entry->defined_==true)continue;
+CAbs_lr1_sym*sym= new Err_bad_th_in_list;
+sym->set_who_created("linker.w",__LINE__);
+
+thread_attributes*th_goodies= ((th_in_stbl*)tbl_entry->symbol_)->thread_in_stbl();
+sym->set_rc(*th_goodies);
+Error_queue.push_back(*sym);
+}
+/*15:*/
+//line 34 "/usr/local/yacco2/o2linker/prog.w"
+
+if(Error_queue.empty()!=true){
+DUMP_ERROR_QUEUE(Error_queue);
+return 1;
+}
+
+/*:15*/
+//line 187 "/usr/local/yacco2/o2linker/prog.w"
+
+
+/*:21*/
+//line 1124 "/usr/local/yacco2/o2linker/prog.w"
+
+/*23:*/
+//line 263 "/usr/local/yacco2/o2linker/prog.w"
+
+cout<<"Sort thread dictionary"<<endl;
+stable_sort(GRAMMAR_DICTIONARY.begin(),GRAMMAR_DICTIONARY.end(),sort_threads_criteria);
+
+/*:23*/
+//line 1125 "/usr/local/yacco2/o2linker/prog.w"
+
+/*24:*/
+//line 269 "/usr/local/yacco2/o2linker/prog.w"
+
+yacco2::lrclog<<"Sorted thread dictionary"<<GRAMMAR_DICTIONARY.size()<<std::endl;
+std::vector<table_entry*> ::iterator dth_i= GRAMMAR_DICTIONARY.begin();
+std::vector<table_entry*> ::iterator dth_ie= GRAMMAR_DICTIONARY.end();
+int pos(-1);
+for(;dth_i!=dth_ie;++dth_i){
+++pos;
+table_entry*tbl_entry= *dth_i;
+thread_attributes*th_goodies= ((th_in_stbl*)tbl_entry->symbol_)->thread_in_stbl();
+yacco2::lrclog<<"tbl entry*: "
+<<tbl_entry<<" th_goodies*: "<<th_goodies
+<<" "<<pos<<":"<<th_goodies->th_enum_
+<<" mono: "<<th_goodies->monolithic_
+<<" thread name: "<<th_goodies->thread_name_->c_string()->c_str()
+<<" FQN: "<<th_goodies->fully_qualified_th_name_.c_str()
+<<" K: "<<th_goodies->fsm_comments_->c_string()->c_str()
+<<std::endl;
+}
+
+/*:24*/
+//line 1126 "/usr/local/yacco2/o2linker/prog.w"
+
+/*25:*/
+//line 291 "/usr/local/yacco2/o2linker/prog.w"
+
+std::vector<table_entry*> ::iterator ri= GRAMMAR_DICTIONARY.begin();
+std::vector<table_entry*> ::iterator rie= GRAMMAR_DICTIONARY.end();
+for(int p= -1;ri!=rie;++ri){
+++p;
+table_entry*tbl_entry= *ri;
+thread_attributes*th_goodies= ((th_in_stbl*)tbl_entry->symbol_)->thread_in_stbl();
+th_goodies->th_enum_= p;
+if(th_goodies->monolithic_=='n')++NO_OF_THREADS;
+}
+
+/*:25*/
+//line 1127 "/usr/local/yacco2/o2linker/prog.w"
+
+/*26:*/
+//line 304 "/usr/local/yacco2/o2linker/prog.w"
+
+int max_thds_supported= SPECULATIVE_NO_BIT_WORDS*BITS_PER_WORD;
+if(NO_OF_THREADS> max_thds_supported){
+char a[SMALL_BUFFER_4K];
+
+KCHARP msg=
+"Error: not enough space for thread bit map manufacture!"
+" # threads: %i, Linker's maximum no of threads supported: %i. \n"
+" Please expand SPECULATIVE_NO_BIT_WORDS";
+sprintf(a,msg,NO_OF_THREADS,max_thds_supported);
+Yacco2_faulty_precondition(msg,__FILE__,__LINE__);
+exit(1);
+}
+
+/*:26*/
+//line 1128 "/usr/local/yacco2/o2linker/prog.w"
+
+/*36:*/
+//line 475 "/usr/local/yacco2/o2linker/prog.w"
+
+/*34:*/
+//line 447 "/usr/local/yacco2/o2linker/prog.w"
+
+for(int vi= 0;vi<NO_OF_THREADS;++vi){
+Visit_graph[vi]= 'n';
+}
+
+/*:34*/
+//line 476 "/usr/local/yacco2/o2linker/prog.w"
+
+
+std::vector<table_entry*> ::iterator thi= GRAMMAR_DICTIONARY.begin();
+std::vector<table_entry*> ::iterator thie= GRAMMAR_DICTIONARY.end();
+for(;thi!=thie;++thi){
+th_in_stbl*th_tbl= (th_in_stbl*)(*thi)->symbol_;
+thread_attributes*th_att= th_tbl->thread_in_stbl();
+if(th_att->monolithic_=='n'){
+yacco2::lrclog<<"thread being walked: "
+<<th_att->thread_name_->c_string()->c_str()<<" id: "
+<<th_att->th_enum_<<std::endl;
+/*35:*/
+//line 454 "/usr/local/yacco2/o2linker/prog.w"
+
+for(int vi= 0;vi<NO_OF_THREADS;++vi){
+Visit_graph[vi]= 'n';
+}
+
+/*:35*/
+//line 487 "/usr/local/yacco2/o2linker/prog.w"
+
+crt_fset_of_thread(*th_att,th_att->th_enum_,*th_att);
+}
+}
+thi= GRAMMAR_DICTIONARY.begin();
+thie= GRAMMAR_DICTIONARY.end();
+for(;thi!=thie;++thi){
+th_in_stbl*th_tbl= (th_in_stbl*)(*thi)->symbol_;
+thread_attributes*th_att= th_tbl->thread_in_stbl();
+/*35:*/
+//line 454 "/usr/local/yacco2/o2linker/prog.w"
+
+for(int vi= 0;vi<NO_OF_THREADS;++vi){
+Visit_graph[vi]= 'n';
+}
+
+/*:35*/
+//line 496 "/usr/local/yacco2/o2linker/prog.w"
+
+crt_called_thread_graph(*th_att);
+}
+
+/*:36*/
+//line 1129 "/usr/local/yacco2/o2linker/prog.w"
+
+/*51:*/
+//line 748 "/usr/local/yacco2/o2linker/prog.w"
+
+cout<<"Emit file name: "<<linker_cntl_file_fsm.emitfile_filename_.c_str()<<endl;
+ofstream ofile(linker_cntl_file_fsm.emitfile_filename_.c_str(),ios::out);
+if(!ofile){
+cout<<"Error - can't open emit file: "
+<<linker_cntl_file_fsm.emitfile_filename_.c_str()<<endl;
+return 1;
+}
+emit_cpp_preamble(ofile
+,linker_cntl_file_fsm.emitfile_filename_.c_str()
+,linker_cntl_file_fsm.preamble_srce_->syntax_code()->c_str());
+emit_global_thread_include_files(ofile);
+emit_global_bit_maps(ofile);
+if(NO_OF_THREADS==0){
+emit_no_threads(ofile);
+}else{
+emit_global_thread_stable(ofile);
+emit_T_fs_of_potential_threads(ofile);
+}
+ofile.close();
+
+/*:51*/
+//line 1130 "/usr/local/yacco2/o2linker/prog.w"
+
+/*50:*/
+//line 727 "/usr/local/yacco2/o2linker/prog.w"
+
+gen_each_grammar_s_referenced_threads();
+char big_buf_[BIG_BUFFER_32K];
+std::string w_linker_filename_("o2linker_doc.w");
+std::ofstream ow_linker_file_;
+ow_linker_file_.open(w_linker_filename_.c_str(),ios_base::out|ios::trunc);
+/*46:*/
+//line 640 "/usr/local/yacco2/o2linker/prog.w"
+
+KCHARP w_doc_index=
+"\\input \"supp-pdf\"\n"
+"\\input \"/usr/local/yacco2/diagrams/o2mac.tex\"\n"
+"\\IDXlinkerdoctitle{%s}{%s}{%s}";
+char xlate_file[Max_cweb_item_size];xlate_file[0]= (char)0;
+char xlate_fscfile[Max_cweb_item_size];xlate_fscfile[0]= (char)0;
+XLATE_SYMBOLS_FOR_cweave(w_linker_filename_.c_str(),xlate_file);
+XLATE_SYMBOLS_FOR_cweave(cntl_file_name.c_str(),xlate_fscfile);
+int x= sprintf(big_buf_
+,w_doc_index
+,xlate_file
+,xlate_file
+,xlate_fscfile
+);
+ow_linker_file_.write(big_buf_,x);
+ow_linker_file_<<std::endl;
+KCHARP w_doc_comments=
+"@** O2linker Index of Grammars.\\fbreak\n"
+"The grammars are sorted lexicographically into 2 parts:\n"
+"threads followed by the stand alone grammars.\n"
+"Each grammar's called threads graph is determined from their \n"
+" ``list-of-transitive-threads''\n"
+"derived from this construct.%s";
+x= sprintf(big_buf_,w_doc_comments," ");
+ow_linker_file_.write(big_buf_,x);
+ow_linker_file_<<std::endl;
+
+/*:46*/
+//line 733 "/usr/local/yacco2/o2linker/prog.w"
+
+/*47:*/
+//line 669 "/usr/local/yacco2/o2linker/prog.w"
+
+KCHARP w_grammar=
+"@*2 %s";
+KCHARP w_comments=
+"\\Linkeridxentryk{%s}";
+KCHARP w_called_threads=
+"\\Linkercalledthreadstitle%s";
+char xlate_gfile[Max_cweb_item_size];
+char rebuild_comment[Max_cweb_item_size];
+char fandk[Max_cweb_item_size];
+char xlate_thnm[Max_cweb_item_size];
+char xlate_tnm[Max_cweb_item_size];
+
+std::vector<table_entry*> ::iterator ithi= GRAMMAR_DICTIONARY.begin();
+std::vector<table_entry*> ::iterator ithie= GRAMMAR_DICTIONARY.end();
+for(;ithi!=ithie;++ithi){
+xlate_gfile[0]= (char)0;
+rebuild_comment[0]= (char)0;
+fandk[0]= (char)0;
+xlate_thnm[0]= (char)0;
+xlate_tnm[0]= (char)0;
+
+table_entry*tbl_entry= *ithi;
+thread_attributes*th_att= ((th_in_stbl*)tbl_entry->symbol_)->thread_in_stbl();
+/*42:*/
+//line 547 "/usr/local/yacco2/o2linker/prog.w"
+
+XLATE_SYMBOLS_FOR_cweave(th_att->thread_name_->c_string()->c_str(),xlate_gfile);
+XLATE_SYMBOLS_FOR_cweave(th_att->fsm_comments_->c_string()->c_str(),rebuild_comment);
+strcat(fandk,xlate_gfile);
+strcat(fandk," --- ");
+strcat(fandk,rebuild_comment);
+int fandk_len= strlen(fandk);
+if(fandk_len<CWEAVE_TITLE_LIMIT){
+if(fandk[fandk_len-1]!='.'){
+strcat(fandk,".");
+}
+}else{
+if(fandk_len==CWEAVE_TITLE_LIMIT){
+if(fandk[CWEAVE_TITLE_LIMIT-1]!='.'){
+strcat(fandk,".");
+}
+}else{
+fandk[CWEAVE_TITLE_LIMIT]= (char)0;
+strcat(fandk,"$\\ldots$ .");
+}
+}
+int x= sprintf(big_buf_
+,w_grammar
+,fandk
+);
+ow_linker_file_.write(big_buf_,x);
+ow_linker_file_<<std::endl;
+x= sprintf(big_buf_
+,w_comments
+,rebuild_comment
+);
+ow_linker_file_.write(big_buf_,x);
+ow_linker_file_<<std::endl;
+x= sprintf(big_buf_
+,w_called_threads," "
+);
+ow_linker_file_.write(big_buf_,x);
+ow_linker_file_<<std::endl;
+
+/*:42*/
+//line 693 "/usr/local/yacco2/o2linker/prog.w"
+
+/*43:*/
+//line 587 "/usr/local/yacco2/o2linker/prog.w"
+
+prt_called_thread_list_ast_functor prt_functr(&PRINT_CALLED_THREAD_LIST);
+prt_functr.o_file(&ow_linker_file_);
+ast_prefix pre(*th_att->called_thread_graph_,&prt_functr);
+while(pre.base_stk_.cur_stk_rec()!=0){
+pre.exec();
+}
+
+/*:43*/
+//line 694 "/usr/local/yacco2/o2linker/prog.w"
+
+/*45:*/
+//line 619 "/usr/local/yacco2/o2linker/prog.w"
+
+ow_linker_file_<<"{\\parindent=6pc"<<endl;
+ow_linker_file_<<"\\item{First set:}"<<std::endl;
+KCHARP fs=
+"%s\n"
+"@.%s@>";
+INT_SET_ITER_type fsi= th_att->fs_.begin();
+INT_SET_ITER_type fsie= th_att->fs_.end();
+char xlate_tnm[Max_cweb_item_size];
+for(;fsi!=fsie;++fsi){
+int tenum= *fsi;
+table_entry*t_entry= T_DICTIONARY[tenum];
+tth_in_stbl*t_in_stbl= (tth_in_stbl*)t_entry->symbol_;
+T_attributes*t_att= t_in_stbl->t_in_stbl();
+XLATE_SYMBOLS_FOR_cweave(t_att->fully_qualified_T_name_.c_str(),xlate_tnm);
+int x= sprintf(big_buf_,fs,xlate_tnm,xlate_tnm);
+ow_linker_file_.write(big_buf_,x);
+ow_linker_file_<<std::endl;
+}
+
+/*:45*/
+//line 695 "/usr/local/yacco2/o2linker/prog.w"
+
+/*44:*/
+//line 596 "/usr/local/yacco2/o2linker/prog.w"
+
+std::map<std::string,std::vector<std::string> > ::iterator ti=
+USED_THREADS_LIST.find(th_att->thread_name_->c_string()->c_str());
+ow_linker_file_<<"{\\parindent=6pc"<<endl;
+ow_linker_file_<<"\\item{Used threads:}"<<std::endl;
+KCHARP used_threads=
+"%s\n"
+"@.%s@>";
+std::vector<std::string> &tt= ti->second;
+std::vector<std::string> ::iterator tti= tt.begin();
+std::vector<std::string> ::iterator ttie= tt.end();
+char xlate_thnm[Max_cweb_item_size];
+for(;tti!=ttie;++tti){
+XLATE_SYMBOLS_FOR_cweave(tti->c_str(),xlate_thnm);
+int x= sprintf(big_buf_,used_threads,xlate_thnm,xlate_thnm);
+ow_linker_file_.write(big_buf_,x);
+ow_linker_file_<<std::endl;
+}
+if(ti->second.empty()==YES)ow_linker_file_<<" none"<<endl;
+ow_linker_file_<<"}"<<endl;
+
+/*:44*/
+//line 696 "/usr/local/yacco2/o2linker/prog.w"
+
+}
+
+/*:47*/
+//line 734 "/usr/local/yacco2/o2linker/prog.w"
+
+/*48:*/
+//line 700 "/usr/local/yacco2/o2linker/prog.w"
+
+KCHARP w_fsc_file_listing=
+"@** First set control file (fsc) listing.\\fbreak\n"
+"File : ``%s''\\fbreak\n"
+"\\let\\setuplistinghook = \\relax\n"
+"\\listing{\"%s\"}\n";
+char xlated_filename[Max_cweb_item_size];
+
+XLATE_SYMBOLS_FOR_cweave(cntl_file_name.c_str(),xlated_filename);
+x= sprintf(big_buf_
+,w_fsc_file_listing
+,xlated_filename
+,cntl_file_name.c_str()
+);
+ow_linker_file_.write(big_buf_,x);
+ow_linker_file_<<std::endl;
+
+/*:48*/
+//line 735 "/usr/local/yacco2/o2linker/prog.w"
+
+/*49:*/
+//line 718 "/usr/local/yacco2/o2linker/prog.w"
+
+KCHARP w_index=
+"@** Index.%s";
+x= sprintf(big_buf_,w_index," ");
+ow_linker_file_.write(big_buf_,x);
+ow_linker_file_<<std::endl;
+
+
+/*:49*/
+//line 736 "/usr/local/yacco2/o2linker/prog.w"
+
+ow_linker_file_.close();
+
+/*:50*/
+//line 1131 "/usr/local/yacco2/o2linker/prog.w"
+
+
+return 0;
+}
+//line 1 "/usr/local/yacco2/o2linker/o2linker_defs.w"
+
+
+
+
+
+
+
+/*:66*/
+//line 42 "/usr/local/yacco2/o2linker/includes.w"
+
+//line 20 "./o2linker.w"
+/*:89*/
diff --git a/web/yacco2/o2linker/o2linker.h b/web/yacco2/o2linker/o2linker.h
new file mode 100644
index 0000000000..a1bd6aea5d
--- /dev/null
+++ b/web/yacco2/o2linker/o2linker.h
@@ -0,0 +1,60 @@
+/*88:*/
+//line 29 "/usr/local/yacco2/o2linker/includes.w"
+
+#define SPECULATIVE_NO_BIT_WORDS 20
+#define LR1_QUESTIONABLE_SHIFT_OPERATOR 0
+#define LR1_EOG 1
+#define LR1_EOLR 2
+#define LR1_PARALLEL_OPERATOR 3
+#define LR1_REDUCE_OPERATOR 4
+#define LR1_PROCEDURE_CALL_OPERATOR 7
+#define LR1_INVISIBLE_SHIFT_OPERATOR 5
+#define LR1_ALL_SHIFT_OPERATOR 6
+#define LR1_FSET_TRANSIENCE_OPERATOR 7
+#define SMALL_BUFFER_4K 1024*4
+#define BITS_PER_WORD 32
+#define TOTAL_NO_BIT_WORDS 1024*2*100 \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+
+
+//line 30 "/usr/local/yacco2/o2linker/includes.w"
+
+#ifndef o2linker__
+#define o2linker__ 1
+/*86:*/
+//line 12 "/usr/local/yacco2/o2linker/includes.w"
+
+#include "globals.h"
+#include "yacco2_stbl.h"
+using namespace yacco2_stbl;
+#include "o2linker_externs.h"
+#include "link_cleanser.h"
+#include "t_alphabet.h"
+#include "fsc_file.h"
+
+
+/*:86*/
+//line 33 "/usr/local/yacco2/o2linker/includes.w"
+
+/*14:*/
+//line 24 "/usr/local/yacco2/o2linker/prog.w"
+
+extern int NO_OF_THREADS;
+extern int NO_WORDS_FOR_BIT_MAP;
+
+/*:14*//*28:*/
+//line 320 "/usr/local/yacco2/o2linker/prog.w"
+
+extern char Visit_graph[RESERVE_FIXED_NO_THREADS];
+/*:28*/
+//line 34 "/usr/local/yacco2/o2linker/includes.w"
+
+#endif
+
+/*:88*/
diff --git a/web/yacco2/o2linker/o2linker.w b/web/yacco2/o2linker/o2linker.w
new file mode 100644
index 0000000000..3bd40feafd
--- /dev/null
+++ b/web/yacco2/o2linker/o2linker.w
@@ -0,0 +1,20 @@
+@q file: o2linker.w@>
+@q% Copyright Dave Bone 1998 - 2015@>
+@q% /*@>
+@q% This Source Code Form is subject to the terms of the Mozilla Public@>
+@q% License, v. 2.0. If a copy of the MPL was not distributed with this@>
+@q% file, You can obtain one at http://mozilla.org/MPL/2.0/.@>
+@q% */@>
+\input "eplain"
+\input "supp-pdf"
+\input"/usr/local/yacco2/diagrams/o2mac.tex"
+@i "/usr/local/yacco2/license.w"
+@i "/usr/local/yacco2/o2linker/intro.w"
+@i "/usr/local/yacco2/o2linker/prog.w"
+@i "/usr/local/yacco2/o2linker/o2linker_defs.w"
+@i "/usr/local/yacco2/o2linker/pms.w"
+@i "/usr/local/yacco2/o2linker/bugs.w"
+@i "/usr/local/yacco2/o2linker/testsuites.w"
+@i "/usr/local/yacco2/o2linker/sampleoutput.w"
+@i "/usr/local/yacco2/o2linker/includes.w"
+@** Index. \ No newline at end of file
diff --git a/web/yacco2/o2linker/o2linker_defs.cpp b/web/yacco2/o2linker/o2linker_defs.cpp
new file mode 100644
index 0000000000..019c43c330
--- /dev/null
+++ b/web/yacco2/o2linker/o2linker_defs.cpp
@@ -0,0 +1,99 @@
+/*71:*/
+//line 90 "/usr/local/yacco2/o2linker/o2linker_defs.w"
+
+#include "o2linker.h"
+/*68:*/
+//line 10 "/usr/local/yacco2/o2linker/o2linker_defs.w"
+
+extern void PRINT_CALLED_THREAD_LIST(AST*Node,std::ofstream*Ow_linker_file,int Idx)
+{
+char big_buf_[BIG_BUFFER_32K];
+thread_attributes*ta= (thread_attributes*)AST::content(*Node);
+KCHARP w_called_threads=
+"\\Linkercalledthreads{%s}{%i}";
+char xlate_gfile[Max_cweb_item_size];
+XLATE_SYMBOLS_FOR_cweave(ta->thread_name_->c_string()->c_str(),xlate_gfile);
+int x= sprintf(big_buf_
+,w_called_threads
+,xlate_gfile
+,Idx
+);
+(*Ow_linker_file).write(big_buf_,x);
+(*Ow_linker_file)<<endl;
+KCHARP w_called_threads_index=
+"@.%s@>";
+x= sprintf(big_buf_
+,w_called_threads_index
+,xlate_gfile
+);
+(*Ow_linker_file).write(big_buf_,x);
+(*Ow_linker_file)<<endl;
+}
+
+yacco2::functor_result_type
+prt_called_thread_list_ast_functor::operator()(yacco2::ast_base_stack*Stk_env){
+stk_env_= Stk_env;
+srec_= stk_env_->cur_stk_rec_;
+idx_= stk_env_->idx_;
+yacco2::INT pidx= idx_-1;
+cnode_= srec_->node_;
+if(pidx<=0)goto prt_prefix;
+{
+ast_base_stack::s_rec*psrec= stk_env_->stk_rec(pidx);
+}
+prt_prefix:
+/*69:*/
+//line 75 "/usr/local/yacco2/o2linker/o2linker_defs.w"
+
+LOCK_MUTEX(yacco2::TRACE_MU);
+if(yacco2::YACCO2_MU_TRACING__){
+yacco2::lrclog<<"YACCO2_MU_TRACING__::Acquired trace mu"<<std::endl;
+}
+
+/*:69*/
+//line 48 "/usr/local/yacco2/o2linker/o2linker_defs.w"
+
+yacco2::INT no_lt(0);
+for(yacco2::INT x= 0;x<=idx_;++x)
+if(stk_env_->stk_rec(x)->act_==ast_base_stack::left)++no_lt;
+/*70:*/
+//line 83 "/usr/local/yacco2/o2linker/o2linker_defs.w"
+
+if(yacco2::YACCO2_MU_TRACING__){
+yacco2::lrclog<<"YACCO2_MU_TRACING__::Releasing trace mu"<<std::endl;
+}
+UNLOCK_MUTEX(yacco2::TRACE_MU);
+
+/*:70*/
+//line 52 "/usr/local/yacco2/o2linker/o2linker_defs.w"
+
+call_prt_func:
+(*prt_funct_)(cnode_,ow_linker_file_,no_lt+1);
+return accept_node;
+}
+
+prt_called_thread_list_ast_functor::
+prt_called_thread_list_ast_functor(PFF Func)
+:prt_funct_(Func),cnt_(0),ow_linker_file_(0){}
+
+void
+prt_called_thread_list_ast_functor::
+reset_cnt(){
+cnt_= 0;
+}
+void prt_called_thread_list_ast_functor::o_file(std::ofstream*Ow_linker_file){
+ow_linker_file_= Ow_linker_file;
+}
+
+/*:68*/
+//line 92 "/usr/local/yacco2/o2linker/o2linker_defs.w"
+
+//line 1 "/usr/local/yacco2/o2linker/pms.w"
+
+
+
+
+
+
+
+/*:71*/
diff --git a/web/yacco2/o2linker/o2linker_defs.w b/web/yacco2/o2linker/o2linker_defs.w
new file mode 100644
index 0000000000..9beeb1983e
--- /dev/null
+++ b/web/yacco2/o2linker/o2linker_defs.w
@@ -0,0 +1,92 @@
+@q file: o2linker_defs.w@>
+@q% Copyright Dave Bone 1998 - 2015@>
+@q% /*@>
+@q% This Source Code Form is subject to the terms of the Mozilla Public@>
+@q% License, v. 2.0. If a copy of the MPL was not distributed with this@>
+@q% file, You can obtain one at http://mozilla.org/MPL/2.0/.@>
+@q% */@>
+@*1 Structure implementation.
+@*2 |prt_called_thread_list_ast_functor| implementation.
+@<Structure implementations@>=
+extern void PRINT_CALLED_THREAD_LIST(AST* Node,std::ofstream* Ow_linker_file,int Idx)
+{
+ char big_buf_[BIG_BUFFER_32K];
+ thread_attributes* ta = (thread_attributes*)AST::content(*Node);
+ KCHARP w_called_threads =
+ "\\Linkercalledthreads{%s}{%i}";
+ char xlate_gfile[Max_cweb_item_size];
+ XLATE_SYMBOLS_FOR_cweave(ta->thread_name_->c_string()->c_str(),xlate_gfile);
+ int x = sprintf(big_buf_
+ ,w_called_threads
+ ,xlate_gfile
+ ,Idx
+ );
+ (*Ow_linker_file).write(big_buf_,x);
+ (*Ow_linker_file) << endl;
+ KCHARP w_called_threads_index =
+ "@@.%s@@>";
+ x = sprintf(big_buf_
+ ,w_called_threads_index
+ ,xlate_gfile
+ );
+ (*Ow_linker_file).write(big_buf_,x);
+ (*Ow_linker_file) << endl;
+}
+@/
+yacco2::functor_result_type @/
+prt_called_thread_list_ast_functor::operator()(yacco2::ast_base_stack* Stk_env){
+ stk_env_ = Stk_env;
+ srec_ = stk_env_->cur_stk_rec_;
+ idx_ = stk_env_->idx_;
+ yacco2::INT pidx = idx_ - 1;
+ cnode_ = srec_->node_;
+ if(pidx <= 0) goto prt_prefix;
+ {
+ ast_base_stack::s_rec* psrec = stk_env_->stk_rec(pidx);
+ }
+prt_prefix:@/
+@<acquire trace mu@>;
+ yacco2::INT no_lt(0);
+ for (yacco2::INT x = 0; x <= idx_; ++x)
+ if(stk_env_->stk_rec(x)->act_ == ast_base_stack::left) ++no_lt;
+@<release trace mu@>;
+call_prt_func:@/
+ (*prt_funct_)(cnode_,ow_linker_file_,no_lt+1);
+ return accept_node;//continue looping thru ast
+ }
+
+ prt_called_thread_list_ast_functor::
+ prt_called_thread_list_ast_functor(PFF Func)
+ :prt_funct_(Func),cnt_(0),ow_linker_file_(0){}
+
+ void
+ prt_called_thread_list_ast_functor::
+ reset_cnt(){
+ cnt_ = 0;
+ }
+ void prt_called_thread_list_ast_functor::o_file(std::ofstream* Ow_linker_file){
+ ow_linker_file_ = Ow_linker_file;
+ }
+
+@*2 Acquire trace mu.\fbreak
+Used to serialize trace output.
+Sometimes the traced output is skewed due to the threading.
+The output to a global container is not thread safe, so make it by use of a mutex.
+@<acquire trace mu@>=
+ LOCK_MUTEX(yacco2::TRACE_MU);
+if(yacco2::YACCO2_MU_TRACING__){
+ yacco2::lrclog << "YACCO2_MU_TRACING__::Acquired trace mu" << std::endl;
+}
+
+@*2 Release trace mu.\fbreak
+Used to serialize trace output.
+@<release trace mu@>=
+if(yacco2::YACCO2_MU_TRACING__){
+ yacco2::lrclog << "YACCO2_MU_TRACING__::Releasing trace mu" << std::endl;
+}
+ UNLOCK_MUTEX(yacco2::TRACE_MU);
+
+@** Write out |o2linker_defs.cpp| Structure implementations.\fbreak
+@(o2linker_defs.cpp@>=
+#include "o2linker.h"
+@<Structure implementations@>;
diff --git a/web/yacco2/o2linker/o2linker_doc.w b/web/yacco2/o2linker/o2linker_doc.w
new file mode 100644
index 0000000000..a9cac7f2a7
--- /dev/null
+++ b/web/yacco2/o2linker/o2linker_doc.w
@@ -0,0 +1,3195 @@
+@q File: o2linker_def.w @>
+@q% Copyright Dave Bone 1998 - 2015@>
+@q% /*@>
+@q% This Source Code Form is subject to the terms of the Mozilla Public@>
+@q% License, v. 2.0. If a copy of the MPL was not distributed with this@>
+@q% file, You can obtain one at http://mozilla.org/MPL/2.0/.@>
+@q% */@>
+\input "supp-pdf"
+\input "/usr/local/yacco2/diagrams/o2mac.tex"
+\IDXlinkerdoctitle{o2linker\_doc.w}{o2linker\_doc.w}{/yacco2/compiler/grammars/yacco2.fsc}
+@** O2linker Index of Grammars.\fbreak
+The grammars are sorted lexicographically into 2 parts:
+threads followed by the stand alone grammars.
+Each grammar's called threads graph is determined from their
+ ``list-of-transitive-threads''
+derived from this construct.
+@*2 TH\_angled\_string --- Angled string lexer: \LTsign ... \GTsign with c type$\ldots$ .
+\Linkeridxentryk{Angled string lexer: \LTsign ... \GTsign with c type escape sequences.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{TH\_angled\_string}{1}
+@.TH\_angled\_string@>
+{\parindent=6pc
+\item{First set:}
+raw\_less\_than
+@.raw\_less\_than@>
+{\parindent=6pc
+\item{Used threads:}
+ none
+}
+@*2 TH\_bad\_char\_set --- Bad source character set recognizer.
+\Linkeridxentryk{Bad source character set recognizer.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{TH\_bad\_char\_set}{1}
+@.TH\_bad\_char\_set@>
+{\parindent=6pc
+\item{First set:}
+raw\_nul
+@.raw\_nul@>
+raw\_soh
+@.raw\_soh@>
+raw\_stx
+@.raw\_stx@>
+raw\_etx
+@.raw\_etx@>
+raw\_eot
+@.raw\_eot@>
+raw\_enq
+@.raw\_enq@>
+raw\_ack
+@.raw\_ack@>
+raw\_bel
+@.raw\_bel@>
+raw\_bs
+@.raw\_bs@>
+raw\_so
+@.raw\_so@>
+raw\_si
+@.raw\_si@>
+raw\_dle
+@.raw\_dle@>
+raw\_dc1
+@.raw\_dc1@>
+raw\_dc2
+@.raw\_dc2@>
+raw\_dc3
+@.raw\_dc3@>
+raw\_dc4
+@.raw\_dc4@>
+raw\_nak
+@.raw\_nak@>
+raw\_syn
+@.raw\_syn@>
+raw\_etb
+@.raw\_etb@>
+raw\_can
+@.raw\_can@>
+raw\_em
+@.raw\_em@>
+raw\_sub
+@.raw\_sub@>
+raw\_esc
+@.raw\_esc@>
+raw\_fs
+@.raw\_fs@>
+raw\_gs
+@.raw\_gs@>
+raw\_rs
+@.raw\_rs@>
+raw\_us
+@.raw\_us@>
+raw\_del
+@.raw\_del@>
+raw\_x80
+@.raw\_x80@>
+raw\_x81
+@.raw\_x81@>
+raw\_x82
+@.raw\_x82@>
+raw\_x83
+@.raw\_x83@>
+raw\_x84
+@.raw\_x84@>
+raw\_x85
+@.raw\_x85@>
+raw\_x86
+@.raw\_x86@>
+raw\_x87
+@.raw\_x87@>
+raw\_x88
+@.raw\_x88@>
+raw\_x89
+@.raw\_x89@>
+raw\_x8a
+@.raw\_x8a@>
+raw\_x8b
+@.raw\_x8b@>
+raw\_x8c
+@.raw\_x8c@>
+raw\_x8d
+@.raw\_x8d@>
+raw\_x8e
+@.raw\_x8e@>
+raw\_x8f
+@.raw\_x8f@>
+raw\_x90
+@.raw\_x90@>
+raw\_x91
+@.raw\_x91@>
+raw\_x92
+@.raw\_x92@>
+raw\_x93
+@.raw\_x93@>
+raw\_x94
+@.raw\_x94@>
+raw\_x95
+@.raw\_x95@>
+raw\_x96
+@.raw\_x96@>
+raw\_x97
+@.raw\_x97@>
+raw\_x98
+@.raw\_x98@>
+raw\_x99
+@.raw\_x99@>
+raw\_x9a
+@.raw\_x9a@>
+raw\_x9b
+@.raw\_x9b@>
+raw\_x9c
+@.raw\_x9c@>
+raw\_x9d
+@.raw\_x9d@>
+raw\_x9e
+@.raw\_x9e@>
+raw\_x9f
+@.raw\_x9f@>
+raw\_xa0
+@.raw\_xa0@>
+raw\_xa1
+@.raw\_xa1@>
+raw\_xa2
+@.raw\_xa2@>
+raw\_xa3
+@.raw\_xa3@>
+raw\_xa4
+@.raw\_xa4@>
+raw\_xa5
+@.raw\_xa5@>
+raw\_xa6
+@.raw\_xa6@>
+raw\_xa7
+@.raw\_xa7@>
+raw\_xa8
+@.raw\_xa8@>
+raw\_xa9
+@.raw\_xa9@>
+raw\_xaa
+@.raw\_xaa@>
+raw\_xab
+@.raw\_xab@>
+raw\_xac
+@.raw\_xac@>
+raw\_xad
+@.raw\_xad@>
+raw\_xae
+@.raw\_xae@>
+raw\_xaf
+@.raw\_xaf@>
+raw\_xb0
+@.raw\_xb0@>
+raw\_xb1
+@.raw\_xb1@>
+raw\_xb2
+@.raw\_xb2@>
+raw\_xb3
+@.raw\_xb3@>
+raw\_xb4
+@.raw\_xb4@>
+raw\_xb5
+@.raw\_xb5@>
+raw\_xb6
+@.raw\_xb6@>
+raw\_xb7
+@.raw\_xb7@>
+raw\_xb8
+@.raw\_xb8@>
+raw\_xb9
+@.raw\_xb9@>
+raw\_xba
+@.raw\_xba@>
+raw\_xbb
+@.raw\_xbb@>
+raw\_xbc
+@.raw\_xbc@>
+raw\_xbd
+@.raw\_xbd@>
+raw\_xbe
+@.raw\_xbe@>
+raw\_xbf
+@.raw\_xbf@>
+raw\_xc0
+@.raw\_xc0@>
+raw\_xc1
+@.raw\_xc1@>
+raw\_xc2
+@.raw\_xc2@>
+raw\_xc3
+@.raw\_xc3@>
+raw\_xc4
+@.raw\_xc4@>
+raw\_xc5
+@.raw\_xc5@>
+raw\_xc6
+@.raw\_xc6@>
+raw\_xc7
+@.raw\_xc7@>
+raw\_xc8
+@.raw\_xc8@>
+raw\_xc9
+@.raw\_xc9@>
+raw\_xca
+@.raw\_xca@>
+raw\_xcb
+@.raw\_xcb@>
+raw\_xcc
+@.raw\_xcc@>
+raw\_xcd
+@.raw\_xcd@>
+raw\_xce
+@.raw\_xce@>
+raw\_xcf
+@.raw\_xcf@>
+raw\_xd0
+@.raw\_xd0@>
+raw\_xd1
+@.raw\_xd1@>
+raw\_xd2
+@.raw\_xd2@>
+raw\_xd3
+@.raw\_xd3@>
+raw\_xd4
+@.raw\_xd4@>
+raw\_xd5
+@.raw\_xd5@>
+raw\_xd6
+@.raw\_xd6@>
+raw\_xd7
+@.raw\_xd7@>
+raw\_xd8
+@.raw\_xd8@>
+raw\_xd9
+@.raw\_xd9@>
+raw\_xda
+@.raw\_xda@>
+raw\_xdb
+@.raw\_xdb@>
+raw\_xdc
+@.raw\_xdc@>
+raw\_xdd
+@.raw\_xdd@>
+raw\_xde
+@.raw\_xde@>
+raw\_xdf
+@.raw\_xdf@>
+raw\_xe0
+@.raw\_xe0@>
+raw\_xe1
+@.raw\_xe1@>
+raw\_xe2
+@.raw\_xe2@>
+raw\_xe3
+@.raw\_xe3@>
+raw\_xe4
+@.raw\_xe4@>
+raw\_xe5
+@.raw\_xe5@>
+raw\_xe6
+@.raw\_xe6@>
+raw\_xe7
+@.raw\_xe7@>
+raw\_xe8
+@.raw\_xe8@>
+raw\_xe9
+@.raw\_xe9@>
+raw\_xea
+@.raw\_xea@>
+raw\_xeb
+@.raw\_xeb@>
+raw\_xec
+@.raw\_xec@>
+raw\_xed
+@.raw\_xed@>
+raw\_xee
+@.raw\_xee@>
+raw\_xef
+@.raw\_xef@>
+raw\_xf0
+@.raw\_xf0@>
+raw\_xf1
+@.raw\_xf1@>
+raw\_xf2
+@.raw\_xf2@>
+raw\_xf3
+@.raw\_xf3@>
+raw\_xf4
+@.raw\_xf4@>
+raw\_xf5
+@.raw\_xf5@>
+raw\_xf6
+@.raw\_xf6@>
+raw\_xf7
+@.raw\_xf7@>
+raw\_xf8
+@.raw\_xf8@>
+raw\_xf9
+@.raw\_xf9@>
+raw\_xfa
+@.raw\_xfa@>
+raw\_xfb
+@.raw\_xfb@>
+raw\_xfc
+@.raw\_xfc@>
+raw\_xfd
+@.raw\_xfd@>
+raw\_xfe
+@.raw\_xfe@>
+raw\_xff
+@.raw\_xff@>
+{\parindent=6pc
+\item{Used threads:}
+ none
+}
+@*2 TH\_cweb\_comments --- CWEB comments containing directives.
+\Linkeridxentryk{CWEB comments containing directives.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{TH\_cweb\_comments}{1}
+@.TH\_cweb\_comments@>
+{\parindent=6pc
+\item{First set:}
+raw\_slash
+@.raw\_slash@>
+{\parindent=6pc
+\item{Used threads:}
+ none
+}
+@*2 TH\_cweb\_or\_c\_k --- C++ or cweb type comments lexer.
+\Linkeridxentryk{C++ or cweb type comments lexer.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{TH\_cweb\_or\_c\_k}{1}
+@.TH\_cweb\_or\_c\_k@>
+{\parindent=6pc
+\item{First set:}
+raw\_slash
+@.raw\_slash@>
+{\parindent=6pc
+\item{Used threads:}
+ none
+}
+@*2 TH\_c\_comments --- C++ type comments lexer.
+\Linkeridxentryk{C++ type comments lexer.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{TH\_c\_comments}{1}
+@.TH\_c\_comments@>
+{\parindent=6pc
+\item{First set:}
+raw\_slash
+@.raw\_slash@>
+{\parindent=6pc
+\item{Used threads:}
+ none
+}
+@*2 TH\_c\_literal --- C literal lexer.
+\Linkeridxentryk{C literal lexer.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{TH\_c\_literal}{1}
+@.TH\_c\_literal@>
+{\parindent=6pc
+\item{First set:}
+raw\_right\_quote
+@.raw\_right\_quote@>
+{\parindent=6pc
+\item{Used threads:}
+ none
+}
+@*2 TH\_c\_string --- C string lexer.
+\Linkeridxentryk{C string lexer.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{TH\_c\_string}{1}
+@.TH\_c\_string@>
+{\parindent=6pc
+\item{First set:}
+raw\_dbl\_quote
+@.raw\_dbl\_quote@>
+{\parindent=6pc
+\item{Used threads:}
+ none
+}
+@*2 TH\_dbl\_colon --- This one's for the thread's name :: lexer.
+\Linkeridxentryk{This one's for the thread's name :: lexer.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{TH\_dbl\_colon}{1}
+@.TH\_dbl\_colon@>
+{\parindent=6pc
+\item{First set:}
+raw\_colon
+@.raw\_colon@>
+{\parindent=6pc
+\item{Used threads:}
+ none
+}
+@*2 TH\_eol --- end-of-line recognizer --- Unix, Mac, and Microsoft supported s$\ldots$ .
+\Linkeridxentryk{end-of-line recognizer --- Unix, Mac, and Microsoft supported styles.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{TH\_eol}{1}
+@.TH\_eol@>
+{\parindent=6pc
+\item{First set:}
+raw\_lf
+@.raw\_lf@>
+raw\_cr
+@.raw\_cr@>
+{\parindent=6pc
+\item{Used threads:}
+ none
+}
+@*2 TH\_err\_symbols\_ph\_th --- Parse Error vocabulary.
+\Linkeridxentryk{Parse Error vocabulary.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{TH\_err\_symbols\_ph\_th}{1}
+@.TH\_err\_symbols\_ph\_th@>
+\Linkercalledthreads{TH\_lint\_balls}{2}
+@.TH\_lint\_balls@>
+\Linkercalledthreads{TH\_ws}{3}
+@.TH\_ws@>
+\Linkercalledthreads{TH\_c\_comments}{3}
+@.TH\_c\_comments@>
+\Linkercalledthreads{TH\_eol}{3}
+@.TH\_eol@>
+{\parindent=6pc
+\item{First set:}
+LR1\_questionable\_shift\_operator
+@.LR1\_questionable\_shift\_operator@>
+raw\_ht
+@.raw\_ht@>
+raw\_lf
+@.raw\_lf@>
+raw\_vt
+@.raw\_vt@>
+raw\_ff
+@.raw\_ff@>
+raw\_cr
+@.raw\_cr@>
+raw\_sp
+@.raw\_sp@>
+raw\_open\_bracket
+@.raw\_open\_bracket@>
+raw\_slash
+@.raw\_slash@>
+{\parindent=6pc
+\item{Used threads:}
+TH\_identifier
+@.TH\_identifier@>
+TH\_lint\_balls
+@.TH\_lint\_balls@>
+TH\_term\_def\_ph
+@.TH\_term\_def\_ph@>
+}
+@*2 TH\_esc\_seq --- C type escape sequence recognizer.
+\Linkeridxentryk{C type escape sequence recognizer.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{TH\_esc\_seq}{1}
+@.TH\_esc\_seq@>
+{\parindent=6pc
+\item{First set:}
+raw\_back\_slash
+@.raw\_back\_slash@>
+{\parindent=6pc
+\item{Used threads:}
+ none
+}
+@*2 TH\_fsm\_class\_phrase\_th --- Parse the fsm-class grammar construct.
+\Linkeridxentryk{Parse the fsm-class grammar construct.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{TH\_fsm\_class\_phrase\_th}{1}
+@.TH\_fsm\_class\_phrase\_th@>
+\Linkercalledthreads{TH\_identifier}{2}
+@.TH\_identifier@>
+{\parindent=6pc
+\item{First set:}
+LR1\_questionable\_shift\_operator
+@.LR1\_questionable\_shift\_operator@>
+raw\_A
+@.raw\_A@>
+raw\_B
+@.raw\_B@>
+raw\_C
+@.raw\_C@>
+raw\_D
+@.raw\_D@>
+raw\_E
+@.raw\_E@>
+raw\_F
+@.raw\_F@>
+raw\_G
+@.raw\_G@>
+raw\_H
+@.raw\_H@>
+raw\_I
+@.raw\_I@>
+raw\_J
+@.raw\_J@>
+raw\_K
+@.raw\_K@>
+raw\_L
+@.raw\_L@>
+raw\_M
+@.raw\_M@>
+raw\_N
+@.raw\_N@>
+raw\_O
+@.raw\_O@>
+raw\_P
+@.raw\_P@>
+raw\_Q
+@.raw\_Q@>
+raw\_R
+@.raw\_R@>
+raw\_S
+@.raw\_S@>
+raw\_T
+@.raw\_T@>
+raw\_U
+@.raw\_U@>
+raw\_V
+@.raw\_V@>
+raw\_W
+@.raw\_W@>
+raw\_X
+@.raw\_X@>
+raw\_Y
+@.raw\_Y@>
+raw\_Z
+@.raw\_Z@>
+raw\_a
+@.raw\_a@>
+raw\_b
+@.raw\_b@>
+raw\_c
+@.raw\_c@>
+raw\_d
+@.raw\_d@>
+raw\_e
+@.raw\_e@>
+raw\_f
+@.raw\_f@>
+raw\_g
+@.raw\_g@>
+raw\_h
+@.raw\_h@>
+raw\_i
+@.raw\_i@>
+raw\_j
+@.raw\_j@>
+raw\_k
+@.raw\_k@>
+raw\_l
+@.raw\_l@>
+raw\_m
+@.raw\_m@>
+raw\_n
+@.raw\_n@>
+raw\_o
+@.raw\_o@>
+raw\_p
+@.raw\_p@>
+raw\_q
+@.raw\_q@>
+raw\_r
+@.raw\_r@>
+raw\_s
+@.raw\_s@>
+raw\_t
+@.raw\_t@>
+raw\_u
+@.raw\_u@>
+raw\_v
+@.raw\_v@>
+raw\_w
+@.raw\_w@>
+raw\_x
+@.raw\_x@>
+raw\_y
+@.raw\_y@>
+raw\_z
+@.raw\_z@>
+{\parindent=6pc
+\item{Used threads:}
+TH\_cweb\_or\_c\_k
+@.TH\_cweb\_or\_c\_k@>
+TH\_identifier
+@.TH\_identifier@>
+TH\_lint\_balls
+@.TH\_lint\_balls@>
+TH\_o2\_sdc
+@.TH\_o2\_sdc@>
+}
+@*2 TH\_fsm\_phrase\_th --- Parse grammar's fsm phrase along with its directive$\ldots$ .
+\Linkeridxentryk{Parse grammar's fsm phrase along with its directives.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{TH\_fsm\_phrase\_th}{1}
+@.TH\_fsm\_phrase\_th@>
+\Linkercalledthreads{TH\_lint\_balls}{2}
+@.TH\_lint\_balls@>
+\Linkercalledthreads{TH\_ws}{3}
+@.TH\_ws@>
+\Linkercalledthreads{TH\_c\_comments}{3}
+@.TH\_c\_comments@>
+\Linkercalledthreads{TH\_eol}{3}
+@.TH\_eol@>
+{\parindent=6pc
+\item{First set:}
+LR1\_questionable\_shift\_operator
+@.LR1\_questionable\_shift\_operator@>
+raw\_ht
+@.raw\_ht@>
+raw\_lf
+@.raw\_lf@>
+raw\_vt
+@.raw\_vt@>
+raw\_ff
+@.raw\_ff@>
+raw\_cr
+@.raw\_cr@>
+raw\_sp
+@.raw\_sp@>
+raw\_open\_bracket
+@.raw\_open\_bracket@>
+raw\_slash
+@.raw\_slash@>
+{\parindent=6pc
+\item{Used threads:}
+TH\_c\_string
+@.TH\_c\_string@>
+TH\_fsm\_class\_phrase\_th
+@.TH\_fsm\_class\_phrase\_th@>
+TH\_identifier
+@.TH\_identifier@>
+TH\_lint\_balls
+@.TH\_lint\_balls@>
+}
+@*2 TH\_identifier --- Yacco2 identifiers lexer with symbol table lookup.
+\Linkeridxentryk{Yacco2 identifiers lexer with symbol table lookup.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{TH\_identifier}{1}
+@.TH\_identifier@>
+{\parindent=6pc
+\item{First set:}
+raw\_A
+@.raw\_A@>
+raw\_B
+@.raw\_B@>
+raw\_C
+@.raw\_C@>
+raw\_D
+@.raw\_D@>
+raw\_E
+@.raw\_E@>
+raw\_F
+@.raw\_F@>
+raw\_G
+@.raw\_G@>
+raw\_H
+@.raw\_H@>
+raw\_I
+@.raw\_I@>
+raw\_J
+@.raw\_J@>
+raw\_K
+@.raw\_K@>
+raw\_L
+@.raw\_L@>
+raw\_M
+@.raw\_M@>
+raw\_N
+@.raw\_N@>
+raw\_O
+@.raw\_O@>
+raw\_P
+@.raw\_P@>
+raw\_Q
+@.raw\_Q@>
+raw\_R
+@.raw\_R@>
+raw\_S
+@.raw\_S@>
+raw\_T
+@.raw\_T@>
+raw\_U
+@.raw\_U@>
+raw\_V
+@.raw\_V@>
+raw\_W
+@.raw\_W@>
+raw\_X
+@.raw\_X@>
+raw\_Y
+@.raw\_Y@>
+raw\_Z
+@.raw\_Z@>
+raw\_a
+@.raw\_a@>
+raw\_b
+@.raw\_b@>
+raw\_c
+@.raw\_c@>
+raw\_d
+@.raw\_d@>
+raw\_e
+@.raw\_e@>
+raw\_f
+@.raw\_f@>
+raw\_g
+@.raw\_g@>
+raw\_h
+@.raw\_h@>
+raw\_i
+@.raw\_i@>
+raw\_j
+@.raw\_j@>
+raw\_k
+@.raw\_k@>
+raw\_l
+@.raw\_l@>
+raw\_m
+@.raw\_m@>
+raw\_n
+@.raw\_n@>
+raw\_o
+@.raw\_o@>
+raw\_p
+@.raw\_p@>
+raw\_q
+@.raw\_q@>
+raw\_r
+@.raw\_r@>
+raw\_s
+@.raw\_s@>
+raw\_t
+@.raw\_t@>
+raw\_u
+@.raw\_u@>
+raw\_v
+@.raw\_v@>
+raw\_w
+@.raw\_w@>
+raw\_x
+@.raw\_x@>
+raw\_y
+@.raw\_y@>
+raw\_z
+@.raw\_z@>
+{\parindent=6pc
+\item{Used threads:}
+ none
+}
+@*2 TH\_int\_no --- Integer number lexer.
+\Linkeridxentryk{Integer number lexer.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{TH\_int\_no}{1}
+@.TH\_int\_no@>
+{\parindent=6pc
+\item{First set:}
+raw\_0
+@.raw\_0@>
+raw\_1
+@.raw\_1@>
+raw\_2
+@.raw\_2@>
+raw\_3
+@.raw\_3@>
+raw\_4
+@.raw\_4@>
+raw\_5
+@.raw\_5@>
+raw\_6
+@.raw\_6@>
+raw\_7
+@.raw\_7@>
+raw\_8
+@.raw\_8@>
+raw\_9
+@.raw\_9@>
+{\parindent=6pc
+\item{Used threads:}
+ none
+}
+@*2 TH\_la\_express\_source --- Lexer: 1st stage of Lookahead source expression$\ldots$ .
+\Linkeridxentryk{Lexer: 1st stage of Lookahead source expression
+ converted into raw character tokens for post evaluation.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{TH\_la\_express\_source}{1}
+@.TH\_la\_express\_source@>
+\Linkercalledthreads{TH\_c\_string}{2}
+@.TH\_c\_string@>
+\Linkercalledthreads{TH\_c\_literal}{2}
+@.TH\_c\_literal@>
+\Linkercalledthreads{TH\_o2\_code\_end}{2}
+@.TH\_o2\_code\_end@>
+\Linkercalledthreads{TH\_identifier}{2}
+@.TH\_identifier@>
+\Linkercalledthreads{TH\_la\_lrk\_T}{2}
+@.TH\_la\_lrk\_T@>
+\Linkercalledthreads{TH\_lint\_balls}{2}
+@.TH\_lint\_balls@>
+\Linkercalledthreads{TH\_ws}{3}
+@.TH\_ws@>
+\Linkercalledthreads{TH\_c\_comments}{3}
+@.TH\_c\_comments@>
+\Linkercalledthreads{TH\_eol}{3}
+@.TH\_eol@>
+{\parindent=6pc
+\item{First set:}
+LR1\_eolr
+@.LR1\_eolr@>
+LR1\_all\_shift\_operator
+@.LR1\_all\_shift\_operator@>
+LR1\_fset\_transience\_operator
+@.LR1\_fset\_transience\_operator@>
+raw\_ht
+@.raw\_ht@>
+raw\_lf
+@.raw\_lf@>
+raw\_vt
+@.raw\_vt@>
+raw\_ff
+@.raw\_ff@>
+raw\_cr
+@.raw\_cr@>
+raw\_sp
+@.raw\_sp@>
+raw\_dbl\_quote
+@.raw\_dbl\_quote@>
+raw\_right\_quote
+@.raw\_right\_quote@>
+raw\_asteric
+@.raw\_asteric@>
+raw\_plus
+@.raw\_plus@>
+raw\_minus
+@.raw\_minus@>
+raw\_slash
+@.raw\_slash@>
+raw\_A
+@.raw\_A@>
+raw\_B
+@.raw\_B@>
+raw\_C
+@.raw\_C@>
+raw\_D
+@.raw\_D@>
+raw\_E
+@.raw\_E@>
+raw\_F
+@.raw\_F@>
+raw\_G
+@.raw\_G@>
+raw\_H
+@.raw\_H@>
+raw\_I
+@.raw\_I@>
+raw\_J
+@.raw\_J@>
+raw\_K
+@.raw\_K@>
+raw\_L
+@.raw\_L@>
+raw\_M
+@.raw\_M@>
+raw\_N
+@.raw\_N@>
+raw\_O
+@.raw\_O@>
+raw\_P
+@.raw\_P@>
+raw\_Q
+@.raw\_Q@>
+raw\_R
+@.raw\_R@>
+raw\_S
+@.raw\_S@>
+raw\_T
+@.raw\_T@>
+raw\_U
+@.raw\_U@>
+raw\_V
+@.raw\_V@>
+raw\_W
+@.raw\_W@>
+raw\_X
+@.raw\_X@>
+raw\_Y
+@.raw\_Y@>
+raw\_Z
+@.raw\_Z@>
+raw\_a
+@.raw\_a@>
+raw\_b
+@.raw\_b@>
+raw\_c
+@.raw\_c@>
+raw\_d
+@.raw\_d@>
+raw\_e
+@.raw\_e@>
+raw\_f
+@.raw\_f@>
+raw\_g
+@.raw\_g@>
+raw\_h
+@.raw\_h@>
+raw\_i
+@.raw\_i@>
+raw\_j
+@.raw\_j@>
+raw\_k
+@.raw\_k@>
+raw\_l
+@.raw\_l@>
+raw\_m
+@.raw\_m@>
+raw\_n
+@.raw\_n@>
+raw\_o
+@.raw\_o@>
+raw\_p
+@.raw\_p@>
+raw\_q
+@.raw\_q@>
+raw\_r
+@.raw\_r@>
+raw\_s
+@.raw\_s@>
+raw\_t
+@.raw\_t@>
+raw\_u
+@.raw\_u@>
+raw\_v
+@.raw\_v@>
+raw\_w
+@.raw\_w@>
+raw\_x
+@.raw\_x@>
+raw\_y
+@.raw\_y@>
+raw\_z
+@.raw\_z@>
+raw\_vertical\_line
+@.raw\_vertical\_line@>
+{\parindent=6pc
+\item{Used threads:}
+TH\_c\_literal
+@.TH\_c\_literal@>
+TH\_c\_string
+@.TH\_c\_string@>
+TH\_identifier
+@.TH\_identifier@>
+TH\_la\_lrk\_T
+@.TH\_la\_lrk\_T@>
+TH\_lint\_balls
+@.TH\_lint\_balls@>
+TH\_o2\_code\_end
+@.TH\_o2\_code\_end@>
+}
+@*2 TH\_la\_lrk\_T --- Unquoted lookahead source symbol recognizer.
+\Linkeridxentryk{Unquoted lookahead source symbol recognizer.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{TH\_la\_lrk\_T}{1}
+@.TH\_la\_lrk\_T@>
+{\parindent=6pc
+\item{First set:}
+raw\_dbl\_quote
+@.raw\_dbl\_quote@>
+raw\_right\_quote
+@.raw\_right\_quote@>
+raw\_vertical\_line
+@.raw\_vertical\_line@>
+{\parindent=6pc
+\item{Used threads:}
+ none
+}
+@*2 TH\_linker\_id --- \olinker identifiers recognizer: uses symbol table.
+\Linkeridxentryk{\olinker identifiers recognizer: uses symbol table.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{TH\_linker\_id}{1}
+@.TH\_linker\_id@>
+{\parindent=6pc
+\item{First set:}
+raw\_A
+@.raw\_A@>
+raw\_B
+@.raw\_B@>
+raw\_C
+@.raw\_C@>
+raw\_D
+@.raw\_D@>
+raw\_E
+@.raw\_E@>
+raw\_F
+@.raw\_F@>
+raw\_G
+@.raw\_G@>
+raw\_H
+@.raw\_H@>
+raw\_I
+@.raw\_I@>
+raw\_J
+@.raw\_J@>
+raw\_K
+@.raw\_K@>
+raw\_L
+@.raw\_L@>
+raw\_M
+@.raw\_M@>
+raw\_N
+@.raw\_N@>
+raw\_O
+@.raw\_O@>
+raw\_P
+@.raw\_P@>
+raw\_Q
+@.raw\_Q@>
+raw\_R
+@.raw\_R@>
+raw\_S
+@.raw\_S@>
+raw\_T
+@.raw\_T@>
+raw\_U
+@.raw\_U@>
+raw\_V
+@.raw\_V@>
+raw\_W
+@.raw\_W@>
+raw\_X
+@.raw\_X@>
+raw\_Y
+@.raw\_Y@>
+raw\_Z
+@.raw\_Z@>
+raw\_a
+@.raw\_a@>
+raw\_b
+@.raw\_b@>
+raw\_c
+@.raw\_c@>
+raw\_d
+@.raw\_d@>
+raw\_e
+@.raw\_e@>
+raw\_f
+@.raw\_f@>
+raw\_g
+@.raw\_g@>
+raw\_h
+@.raw\_h@>
+raw\_i
+@.raw\_i@>
+raw\_j
+@.raw\_j@>
+raw\_k
+@.raw\_k@>
+raw\_l
+@.raw\_l@>
+raw\_m
+@.raw\_m@>
+raw\_n
+@.raw\_n@>
+raw\_o
+@.raw\_o@>
+raw\_p
+@.raw\_p@>
+raw\_q
+@.raw\_q@>
+raw\_r
+@.raw\_r@>
+raw\_s
+@.raw\_s@>
+raw\_t
+@.raw\_t@>
+raw\_u
+@.raw\_u@>
+raw\_v
+@.raw\_v@>
+raw\_w
+@.raw\_w@>
+raw\_x
+@.raw\_x@>
+raw\_y
+@.raw\_y@>
+raw\_z
+@.raw\_z@>
+{\parindent=6pc
+\item{Used threads:}
+ none
+}
+@*2 TH\_linker\_preamble\_code --- \olinker's lexer of preamble code section:
+ $\ldots$ .
+\Linkeridxentryk{\olinker's lexer of preamble code section:
+ similar to Pass3 lexer.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{TH\_linker\_preamble\_code}{1}
+@.TH\_linker\_preamble\_code@>
+\Linkercalledthreads{TH\_c\_comments}{2}
+@.TH\_c\_comments@>
+\Linkercalledthreads{TH\_c\_string}{2}
+@.TH\_c\_string@>
+\Linkercalledthreads{TH\_c\_literal}{2}
+@.TH\_c\_literal@>
+\Linkercalledthreads{TH\_linker\_id}{2}
+@.TH\_linker\_id@>
+{\parindent=6pc
+\item{First set:}
+LR1\_eolr
+@.LR1\_eolr@>
+LR1\_all\_shift\_operator
+@.LR1\_all\_shift\_operator@>
+raw\_dbl\_quote
+@.raw\_dbl\_quote@>
+raw\_right\_quote
+@.raw\_right\_quote@>
+raw\_slash
+@.raw\_slash@>
+raw\_A
+@.raw\_A@>
+raw\_B
+@.raw\_B@>
+raw\_C
+@.raw\_C@>
+raw\_D
+@.raw\_D@>
+raw\_E
+@.raw\_E@>
+raw\_F
+@.raw\_F@>
+raw\_G
+@.raw\_G@>
+raw\_H
+@.raw\_H@>
+raw\_I
+@.raw\_I@>
+raw\_J
+@.raw\_J@>
+raw\_K
+@.raw\_K@>
+raw\_L
+@.raw\_L@>
+raw\_M
+@.raw\_M@>
+raw\_N
+@.raw\_N@>
+raw\_O
+@.raw\_O@>
+raw\_P
+@.raw\_P@>
+raw\_Q
+@.raw\_Q@>
+raw\_R
+@.raw\_R@>
+raw\_S
+@.raw\_S@>
+raw\_T
+@.raw\_T@>
+raw\_U
+@.raw\_U@>
+raw\_V
+@.raw\_V@>
+raw\_W
+@.raw\_W@>
+raw\_X
+@.raw\_X@>
+raw\_Y
+@.raw\_Y@>
+raw\_Z
+@.raw\_Z@>
+raw\_a
+@.raw\_a@>
+raw\_b
+@.raw\_b@>
+raw\_c
+@.raw\_c@>
+raw\_d
+@.raw\_d@>
+raw\_e
+@.raw\_e@>
+raw\_f
+@.raw\_f@>
+raw\_g
+@.raw\_g@>
+raw\_h
+@.raw\_h@>
+raw\_i
+@.raw\_i@>
+raw\_j
+@.raw\_j@>
+raw\_k
+@.raw\_k@>
+raw\_l
+@.raw\_l@>
+raw\_m
+@.raw\_m@>
+raw\_n
+@.raw\_n@>
+raw\_o
+@.raw\_o@>
+raw\_p
+@.raw\_p@>
+raw\_q
+@.raw\_q@>
+raw\_r
+@.raw\_r@>
+raw\_s
+@.raw\_s@>
+raw\_t
+@.raw\_t@>
+raw\_u
+@.raw\_u@>
+raw\_v
+@.raw\_v@>
+raw\_w
+@.raw\_w@>
+raw\_x
+@.raw\_x@>
+raw\_y
+@.raw\_y@>
+raw\_z
+@.raw\_z@>
+{\parindent=6pc
+\item{Used threads:}
+TH\_c\_comments
+@.TH\_c\_comments@>
+TH\_c\_literal
+@.TH\_c\_literal@>
+TH\_c\_string
+@.TH\_c\_string@>
+TH\_linker\_id
+@.TH\_linker\_id@>
+}
+@*2 TH\_lint\_balls --- Is this spring cleaning?.
+\Linkeridxentryk{Is this spring cleaning?}
+\Linkercalledthreadstitle
+\Linkercalledthreads{TH\_lint\_balls}{1}
+@.TH\_lint\_balls@>
+\Linkercalledthreads{TH\_ws}{2}
+@.TH\_ws@>
+\Linkercalledthreads{TH\_c\_comments}{2}
+@.TH\_c\_comments@>
+\Linkercalledthreads{TH\_eol}{2}
+@.TH\_eol@>
+{\parindent=6pc
+\item{First set:}
+raw\_ht
+@.raw\_ht@>
+raw\_lf
+@.raw\_lf@>
+raw\_vt
+@.raw\_vt@>
+raw\_ff
+@.raw\_ff@>
+raw\_cr
+@.raw\_cr@>
+raw\_sp
+@.raw\_sp@>
+raw\_slash
+@.raw\_slash@>
+{\parindent=6pc
+\item{Used threads:}
+TH\_c\_comments
+@.TH\_c\_comments@>
+TH\_eol
+@.TH\_eol@>
+TH\_ws
+@.TH\_ws@>
+}
+@*2 TH\_lr1\_k\_phrase\_th --- Parse lr1 k symbols phrase.
+\Linkeridxentryk{Parse lr1 k symbols phrase.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{TH\_lr1\_k\_phrase\_th}{1}
+@.TH\_lr1\_k\_phrase\_th@>
+\Linkercalledthreads{TH\_lint\_balls}{2}
+@.TH\_lint\_balls@>
+\Linkercalledthreads{TH\_ws}{3}
+@.TH\_ws@>
+\Linkercalledthreads{TH\_c\_comments}{3}
+@.TH\_c\_comments@>
+\Linkercalledthreads{TH\_eol}{3}
+@.TH\_eol@>
+{\parindent=6pc
+\item{First set:}
+LR1\_questionable\_shift\_operator
+@.LR1\_questionable\_shift\_operator@>
+raw\_ht
+@.raw\_ht@>
+raw\_lf
+@.raw\_lf@>
+raw\_vt
+@.raw\_vt@>
+raw\_ff
+@.raw\_ff@>
+raw\_cr
+@.raw\_cr@>
+raw\_sp
+@.raw\_sp@>
+raw\_open\_bracket
+@.raw\_open\_bracket@>
+raw\_slash
+@.raw\_slash@>
+{\parindent=6pc
+\item{Used threads:}
+TH\_cweb\_or\_c\_k
+@.TH\_cweb\_or\_c\_k@>
+TH\_identifier
+@.TH\_identifier@>
+TH\_lint\_balls
+@.TH\_lint\_balls@>
+TH\_o2\_sdc
+@.TH\_o2\_sdc@>
+TH\_term\_def\_ph
+@.TH\_term\_def\_ph@>
+}
+@*2 TH\_o2\_code\_end --- Lexer syntax directed code end marker: \threeasteric.
+\Linkeridxentryk{Lexer syntax directed code end marker: \threeasteric.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{TH\_o2\_code\_end}{1}
+@.TH\_o2\_code\_end@>
+{\parindent=6pc
+\item{First set:}
+raw\_asteric
+@.raw\_asteric@>
+{\parindent=6pc
+\item{Used threads:}
+ none
+}
+@*2 TH\_o2\_lcl\_opt --- \O2's individual command line option recognizer.
+\Linkeridxentryk{\O2's individual command line option recognizer.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{TH\_o2\_lcl\_opt}{1}
+@.TH\_o2\_lcl\_opt@>
+{\parindent=6pc
+\item{First set:}
+raw\_minus
+@.raw\_minus@>
+{\parindent=6pc
+\item{Used threads:}
+ none
+}
+@*2 TH\_o2\_sdc --- \O2's syntax directed code extractor.
+\Linkeridxentryk{\O2's syntax directed code extractor.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{TH\_o2\_sdc}{1}
+@.TH\_o2\_sdc@>
+\Linkercalledthreads{TH\_c\_comments}{2}
+@.TH\_c\_comments@>
+\Linkercalledthreads{TH\_c\_string}{2}
+@.TH\_c\_string@>
+\Linkercalledthreads{TH\_c\_literal}{2}
+@.TH\_c\_literal@>
+\Linkercalledthreads{TH\_o2\_code\_end}{2}
+@.TH\_o2\_code\_end@>
+{\parindent=6pc
+\item{First set:}
+LR1\_eolr
+@.LR1\_eolr@>
+LR1\_all\_shift\_operator
+@.LR1\_all\_shift\_operator@>
+raw\_dbl\_quote
+@.raw\_dbl\_quote@>
+raw\_right\_quote
+@.raw\_right\_quote@>
+raw\_asteric
+@.raw\_asteric@>
+raw\_slash
+@.raw\_slash@>
+{\parindent=6pc
+\item{Used threads:}
+TH\_c\_comments
+@.TH\_c\_comments@>
+TH\_c\_literal
+@.TH\_c\_literal@>
+TH\_c\_string
+@.TH\_c\_string@>
+TH\_o2\_code\_end
+@.TH\_o2\_code\_end@>
+}
+@*2 TH\_parallel\_monitor\_ph --- Parse a rule's arbitration code:
+ into the v$\ldots$ .
+\Linkeridxentryk{Parse a rule's arbitration code:
+ into the valley of someone's dementia...}
+\Linkercalledthreadstitle
+\Linkercalledthreads{TH\_parallel\_monitor\_ph}{1}
+@.TH\_parallel\_monitor\_ph@>
+{\parindent=6pc
+\item{First set:}
+T\_parallel\_control\_monitor
+@.T\_parallel\_control\_monitor@>
+{\parindent=6pc
+\item{Used threads:}
+TH\_cweb\_or\_c\_k
+@.TH\_cweb\_or\_c\_k@>
+TH\_identifier
+@.TH\_identifier@>
+TH\_lint\_balls
+@.TH\_lint\_balls@>
+TH\_o2\_sdc
+@.TH\_o2\_sdc@>
+}
+@*2 TH\_parallel\_oper --- Lexer for Parallel operator: \PARshift.
+\Linkeridxentryk{Lexer for Parallel operator: \PARshift.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{TH\_parallel\_oper}{1}
+@.TH\_parallel\_oper@>
+{\parindent=6pc
+\item{First set:}
+raw\_dbl\_quote
+@.raw\_dbl\_quote@>
+raw\_vertical\_line
+@.raw\_vertical\_line@>
+{\parindent=6pc
+\item{Used threads:}
+ none
+}
+@*2 TH\_parallel\_parser\_ph\_th --- Parse grammar's parallel-parser construct.
+\Linkeridxentryk{Parse grammar's parallel-parser construct.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{TH\_parallel\_parser\_ph\_th}{1}
+@.TH\_parallel\_parser\_ph\_th@>
+\Linkercalledthreads{TH\_lint\_balls}{2}
+@.TH\_lint\_balls@>
+\Linkercalledthreads{TH\_ws}{3}
+@.TH\_ws@>
+\Linkercalledthreads{TH\_c\_comments}{3}
+@.TH\_c\_comments@>
+\Linkercalledthreads{TH\_eol}{3}
+@.TH\_eol@>
+{\parindent=6pc
+\item{First set:}
+LR1\_questionable\_shift\_operator
+@.LR1\_questionable\_shift\_operator@>
+raw\_ht
+@.raw\_ht@>
+raw\_lf
+@.raw\_lf@>
+raw\_vt
+@.raw\_vt@>
+raw\_ff
+@.raw\_ff@>
+raw\_cr
+@.raw\_cr@>
+raw\_sp
+@.raw\_sp@>
+raw\_open\_bracket
+@.raw\_open\_bracket@>
+raw\_slash
+@.raw\_slash@>
+{\parindent=6pc
+\item{Used threads:}
+TH\_identifier
+@.TH\_identifier@>
+TH\_la\_express\_source
+@.TH\_la\_express\_source@>
+TH\_lint\_balls
+@.TH\_lint\_balls@>
+TH\_o2\_code\_end
+@.TH\_o2\_code\_end@>
+}
+@*2 TH\_prefile\_include --- Preprocessor source file from the ``include file''$\ldots$ .
+\Linkeridxentryk{Preprocessor source file from the ``include file'' directive.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{TH\_prefile\_include}{1}
+@.TH\_prefile\_include@>
+{\parindent=6pc
+\item{First set:}
+raw\_at\_sign
+@.raw\_at\_sign@>
+{\parindent=6pc
+\item{Used threads:}
+TH\_c\_string
+@.TH\_c\_string@>
+TH\_eol
+@.TH\_eol@>
+TH\_ws
+@.TH\_ws@>
+}
+@*2 TH\_rc\_phrase\_th --- Raw character vocabulary parser.
+\Linkeridxentryk{Raw character vocabulary parser.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{TH\_rc\_phrase\_th}{1}
+@.TH\_rc\_phrase\_th@>
+\Linkercalledthreads{TH\_lint\_balls}{2}
+@.TH\_lint\_balls@>
+\Linkercalledthreads{TH\_ws}{3}
+@.TH\_ws@>
+\Linkercalledthreads{TH\_c\_comments}{3}
+@.TH\_c\_comments@>
+\Linkercalledthreads{TH\_eol}{3}
+@.TH\_eol@>
+{\parindent=6pc
+\item{First set:}
+LR1\_questionable\_shift\_operator
+@.LR1\_questionable\_shift\_operator@>
+raw\_ht
+@.raw\_ht@>
+raw\_lf
+@.raw\_lf@>
+raw\_vt
+@.raw\_vt@>
+raw\_ff
+@.raw\_ff@>
+raw\_cr
+@.raw\_cr@>
+raw\_sp
+@.raw\_sp@>
+raw\_open\_bracket
+@.raw\_open\_bracket@>
+raw\_slash
+@.raw\_slash@>
+{\parindent=6pc
+\item{Used threads:}
+TH\_identifier
+@.TH\_identifier@>
+TH\_lint\_balls
+@.TH\_lint\_balls@>
+TH\_term\_def\_ph
+@.TH\_term\_def\_ph@>
+}
+@*2 TH\_rhs\_bnd --- Determine end-of-subrule expression within a rule.
+\Linkeridxentryk{Determine end-of-subrule expression within a rule.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{TH\_rhs\_bnd}{1}
+@.TH\_rhs\_bnd@>
+{\parindent=6pc
+\item{First set:}
+LR1\_eog
+@.LR1\_eog@>
+raw\_minus
+@.raw\_minus@>
+raw\_open\_brace
+@.raw\_open\_brace@>
+raw\_close\_brace
+@.raw\_close\_brace@>
+{\parindent=6pc
+\item{Used threads:}
+ none
+}
+@*2 TH\_rhs\_component --- Subule's individual component recognizer except eosu$\ldots$ .
+\Linkeridxentryk{Subule's individual component recognizer except eosubrule.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{TH\_rhs\_component}{1}
+@.TH\_rhs\_component@>
+\Linkercalledthreads{TH\_identifier}{2}
+@.TH\_identifier@>
+\Linkercalledthreads{TH\_c\_string}{2}
+@.TH\_c\_string@>
+\Linkercalledthreads{TH\_unq\_str}{2}
+@.TH\_unq\_str@>
+\Linkercalledthreads{TH\_cweb\_or\_c\_k}{2}
+@.TH\_cweb\_or\_c\_k@>
+{\parindent=6pc
+\item{First set:}
+LR1\_eolr
+@.LR1\_eolr@>
+LR1\_all\_shift\_operator
+@.LR1\_all\_shift\_operator@>
+raw\_dbl\_quote
+@.raw\_dbl\_quote@>
+raw\_slash
+@.raw\_slash@>
+raw\_A
+@.raw\_A@>
+raw\_B
+@.raw\_B@>
+raw\_C
+@.raw\_C@>
+raw\_D
+@.raw\_D@>
+raw\_E
+@.raw\_E@>
+raw\_F
+@.raw\_F@>
+raw\_G
+@.raw\_G@>
+raw\_H
+@.raw\_H@>
+raw\_I
+@.raw\_I@>
+raw\_J
+@.raw\_J@>
+raw\_K
+@.raw\_K@>
+raw\_L
+@.raw\_L@>
+raw\_M
+@.raw\_M@>
+raw\_N
+@.raw\_N@>
+raw\_O
+@.raw\_O@>
+raw\_P
+@.raw\_P@>
+raw\_Q
+@.raw\_Q@>
+raw\_R
+@.raw\_R@>
+raw\_S
+@.raw\_S@>
+raw\_T
+@.raw\_T@>
+raw\_U
+@.raw\_U@>
+raw\_V
+@.raw\_V@>
+raw\_W
+@.raw\_W@>
+raw\_X
+@.raw\_X@>
+raw\_Y
+@.raw\_Y@>
+raw\_Z
+@.raw\_Z@>
+raw\_a
+@.raw\_a@>
+raw\_b
+@.raw\_b@>
+raw\_c
+@.raw\_c@>
+raw\_d
+@.raw\_d@>
+raw\_e
+@.raw\_e@>
+raw\_f
+@.raw\_f@>
+raw\_g
+@.raw\_g@>
+raw\_h
+@.raw\_h@>
+raw\_i
+@.raw\_i@>
+raw\_j
+@.raw\_j@>
+raw\_k
+@.raw\_k@>
+raw\_l
+@.raw\_l@>
+raw\_m
+@.raw\_m@>
+raw\_n
+@.raw\_n@>
+raw\_o
+@.raw\_o@>
+raw\_p
+@.raw\_p@>
+raw\_q
+@.raw\_q@>
+raw\_r
+@.raw\_r@>
+raw\_s
+@.raw\_s@>
+raw\_t
+@.raw\_t@>
+raw\_u
+@.raw\_u@>
+raw\_v
+@.raw\_v@>
+raw\_w
+@.raw\_w@>
+raw\_x
+@.raw\_x@>
+raw\_y
+@.raw\_y@>
+raw\_z
+@.raw\_z@>
+{\parindent=6pc
+\item{Used threads:}
+TH\_c\_string
+@.TH\_c\_string@>
+TH\_cweb\_or\_c\_k
+@.TH\_cweb\_or\_c\_k@>
+TH\_identifier
+@.TH\_identifier@>
+TH\_unq\_str
+@.TH\_unq\_str@>
+}
+@*2 TH\_rtn\_component --- Recognizer of returned T from a thread call expressi$\ldots$ .
+\Linkeridxentryk{Recognizer of returned T from a thread call expression.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{TH\_rtn\_component}{1}
+@.TH\_rtn\_component@>
+\Linkercalledthreads{TH\_identifier}{2}
+@.TH\_identifier@>
+\Linkercalledthreads{TH\_c\_string}{2}
+@.TH\_c\_string@>
+\Linkercalledthreads{TH\_unq\_str}{2}
+@.TH\_unq\_str@>
+{\parindent=6pc
+\item{First set:}
+LR1\_eolr
+@.LR1\_eolr@>
+LR1\_all\_shift\_operator
+@.LR1\_all\_shift\_operator@>
+raw\_dbl\_quote
+@.raw\_dbl\_quote@>
+raw\_A
+@.raw\_A@>
+raw\_B
+@.raw\_B@>
+raw\_C
+@.raw\_C@>
+raw\_D
+@.raw\_D@>
+raw\_E
+@.raw\_E@>
+raw\_F
+@.raw\_F@>
+raw\_G
+@.raw\_G@>
+raw\_H
+@.raw\_H@>
+raw\_I
+@.raw\_I@>
+raw\_J
+@.raw\_J@>
+raw\_K
+@.raw\_K@>
+raw\_L
+@.raw\_L@>
+raw\_M
+@.raw\_M@>
+raw\_N
+@.raw\_N@>
+raw\_O
+@.raw\_O@>
+raw\_P
+@.raw\_P@>
+raw\_Q
+@.raw\_Q@>
+raw\_R
+@.raw\_R@>
+raw\_S
+@.raw\_S@>
+raw\_T
+@.raw\_T@>
+raw\_U
+@.raw\_U@>
+raw\_V
+@.raw\_V@>
+raw\_W
+@.raw\_W@>
+raw\_X
+@.raw\_X@>
+raw\_Y
+@.raw\_Y@>
+raw\_Z
+@.raw\_Z@>
+raw\_a
+@.raw\_a@>
+raw\_b
+@.raw\_b@>
+raw\_c
+@.raw\_c@>
+raw\_d
+@.raw\_d@>
+raw\_e
+@.raw\_e@>
+raw\_f
+@.raw\_f@>
+raw\_g
+@.raw\_g@>
+raw\_h
+@.raw\_h@>
+raw\_i
+@.raw\_i@>
+raw\_j
+@.raw\_j@>
+raw\_k
+@.raw\_k@>
+raw\_l
+@.raw\_l@>
+raw\_m
+@.raw\_m@>
+raw\_n
+@.raw\_n@>
+raw\_o
+@.raw\_o@>
+raw\_p
+@.raw\_p@>
+raw\_q
+@.raw\_q@>
+raw\_r
+@.raw\_r@>
+raw\_s
+@.raw\_s@>
+raw\_t
+@.raw\_t@>
+raw\_u
+@.raw\_u@>
+raw\_v
+@.raw\_v@>
+raw\_w
+@.raw\_w@>
+raw\_x
+@.raw\_x@>
+raw\_y
+@.raw\_y@>
+raw\_z
+@.raw\_z@>
+{\parindent=6pc
+\item{Used threads:}
+TH\_c\_string
+@.TH\_c\_string@>
+TH\_identifier
+@.TH\_identifier@>
+TH\_unq\_str
+@.TH\_unq\_str@>
+}
+@*2 TH\_rules\_phrase\_th --- Parse all of the grammar's rules.
+\Linkeridxentryk{Parse all of the grammar's rules.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{TH\_rules\_phrase\_th}{1}
+@.TH\_rules\_phrase\_th@>
+\Linkercalledthreads{TH\_ws}{2}
+@.TH\_ws@>
+\Linkercalledthreads{TH\_cweb\_or\_c\_k}{2}
+@.TH\_cweb\_or\_c\_k@>
+\Linkercalledthreads{TH\_eol}{2}
+@.TH\_eol@>
+{\parindent=6pc
+\item{First set:}
+LR1\_questionable\_shift\_operator
+@.LR1\_questionable\_shift\_operator@>
+raw\_ht
+@.raw\_ht@>
+raw\_lf
+@.raw\_lf@>
+raw\_vt
+@.raw\_vt@>
+raw\_ff
+@.raw\_ff@>
+raw\_cr
+@.raw\_cr@>
+raw\_sp
+@.raw\_sp@>
+raw\_slash
+@.raw\_slash@>
+raw\_open\_brace
+@.raw\_open\_brace@>
+{\parindent=6pc
+\item{Used threads:}
+TH\_cweb\_or\_c\_k
+@.TH\_cweb\_or\_c\_k@>
+TH\_eol
+@.TH\_eol@>
+TH\_rule\_def\_phrase
+@.TH\_rule\_def\_phrase@>
+TH\_ws
+@.TH\_ws@>
+}
+@*2 TH\_rule\_def\_phrase --- Parse a grammar's rule definition.
+\Linkeridxentryk{Parse a grammar's rule definition.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{TH\_rule\_def\_phrase}{1}
+@.TH\_rule\_def\_phrase@>
+\Linkercalledthreads{TH\_identifier}{2}
+@.TH\_identifier@>
+{\parindent=6pc
+\item{First set:}
+LR1\_questionable\_shift\_operator
+@.LR1\_questionable\_shift\_operator@>
+raw\_A
+@.raw\_A@>
+raw\_B
+@.raw\_B@>
+raw\_C
+@.raw\_C@>
+raw\_D
+@.raw\_D@>
+raw\_E
+@.raw\_E@>
+raw\_F
+@.raw\_F@>
+raw\_G
+@.raw\_G@>
+raw\_H
+@.raw\_H@>
+raw\_I
+@.raw\_I@>
+raw\_J
+@.raw\_J@>
+raw\_K
+@.raw\_K@>
+raw\_L
+@.raw\_L@>
+raw\_M
+@.raw\_M@>
+raw\_N
+@.raw\_N@>
+raw\_O
+@.raw\_O@>
+raw\_P
+@.raw\_P@>
+raw\_Q
+@.raw\_Q@>
+raw\_R
+@.raw\_R@>
+raw\_S
+@.raw\_S@>
+raw\_T
+@.raw\_T@>
+raw\_U
+@.raw\_U@>
+raw\_V
+@.raw\_V@>
+raw\_W
+@.raw\_W@>
+raw\_X
+@.raw\_X@>
+raw\_Y
+@.raw\_Y@>
+raw\_Z
+@.raw\_Z@>
+raw\_a
+@.raw\_a@>
+raw\_b
+@.raw\_b@>
+raw\_c
+@.raw\_c@>
+raw\_d
+@.raw\_d@>
+raw\_e
+@.raw\_e@>
+raw\_f
+@.raw\_f@>
+raw\_g
+@.raw\_g@>
+raw\_h
+@.raw\_h@>
+raw\_i
+@.raw\_i@>
+raw\_j
+@.raw\_j@>
+raw\_k
+@.raw\_k@>
+raw\_l
+@.raw\_l@>
+raw\_m
+@.raw\_m@>
+raw\_n
+@.raw\_n@>
+raw\_o
+@.raw\_o@>
+raw\_p
+@.raw\_p@>
+raw\_q
+@.raw\_q@>
+raw\_r
+@.raw\_r@>
+raw\_s
+@.raw\_s@>
+raw\_t
+@.raw\_t@>
+raw\_u
+@.raw\_u@>
+raw\_v
+@.raw\_v@>
+raw\_w
+@.raw\_w@>
+raw\_x
+@.raw\_x@>
+raw\_y
+@.raw\_y@>
+raw\_z
+@.raw\_z@>
+{\parindent=6pc
+\item{Used threads:}
+TH\_cweb\_or\_c\_k
+@.TH\_cweb\_or\_c\_k@>
+TH\_identifier
+@.TH\_identifier@>
+TH\_lint\_balls
+@.TH\_lint\_balls@>
+TH\_subrules\_phrase
+@.TH\_subrules\_phrase@>
+TH\_t\_def\_delabort\_tags
+@.TH\_t\_def\_delabort\_tags@>
+}
+@*2 TH\_rule\_lhs\_phrase --- Parse a rule's ``lhs'' directive.
+\Linkeridxentryk{Parse a rule's ``lhs'' directive.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{TH\_rule\_lhs\_phrase}{1}
+@.TH\_rule\_lhs\_phrase@>
+{\parindent=6pc
+\item{First set:}
+T\_lhs
+@.T\_lhs@>
+{\parindent=6pc
+\item{Used threads:}
+TH\_cweb\_or\_c\_k
+@.TH\_cweb\_or\_c\_k@>
+TH\_identifier
+@.TH\_identifier@>
+TH\_lint\_balls
+@.TH\_lint\_balls@>
+TH\_o2\_sdc
+@.TH\_o2\_sdc@>
+}
+@*2 TH\_subrules\_phrase --- Parse subrules: into the valley of ...
+\Linkeridxentryk{Parse subrules: into the valley of ...}
+\Linkercalledthreadstitle
+\Linkercalledthreads{TH\_subrules\_phrase}{1}
+@.TH\_subrules\_phrase@>
+\Linkercalledthreads{TH\_subrule\_def}{2}
+@.TH\_subrule\_def@>
+\Linkercalledthreads{TH\_subrule\_vector}{3}
+@.TH\_subrule\_vector@>
+{\parindent=6pc
+\item{First set:}
+LR1\_questionable\_shift\_operator
+@.LR1\_questionable\_shift\_operator@>
+raw\_minus
+@.raw\_minus@>
+{\parindent=6pc
+\item{Used threads:}
+TH\_lint\_balls
+@.TH\_lint\_balls@>
+TH\_subrule\_def
+@.TH\_subrule\_def@>
+}
+@*2 TH\_subrule\_def --- Parse a subrule: into the valley of sin...
+\Linkeridxentryk{Parse a subrule: into the valley of sin...}
+\Linkercalledthreadstitle
+\Linkercalledthreads{TH\_subrule\_def}{1}
+@.TH\_subrule\_def@>
+\Linkercalledthreads{TH\_subrule\_vector}{2}
+@.TH\_subrule\_vector@>
+{\parindent=6pc
+\item{First set:}
+raw\_minus
+@.raw\_minus@>
+{\parindent=6pc
+\item{Used threads:}
+TH\_cweb\_or\_c\_k
+@.TH\_cweb\_or\_c\_k@>
+TH\_dbl\_colon
+@.TH\_dbl\_colon@>
+TH\_identifier
+@.TH\_identifier@>
+TH\_lint\_balls
+@.TH\_lint\_balls@>
+TH\_o2\_sdc
+@.TH\_o2\_sdc@>
+TH\_parallel\_oper
+@.TH\_parallel\_oper@>
+TH\_rhs\_bnd
+@.TH\_rhs\_bnd@>
+TH\_rhs\_component
+@.TH\_rhs\_component@>
+TH\_rtn\_component
+@.TH\_rtn\_component@>
+TH\_subrule\_vector
+@.TH\_subrule\_vector@>
+}
+@*2 TH\_subrule\_vector --- Lexer of subrule begin operator: \subrule.
+\Linkeridxentryk{Lexer of subrule begin operator: \subrule.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{TH\_subrule\_vector}{1}
+@.TH\_subrule\_vector@>
+{\parindent=6pc
+\item{First set:}
+raw\_minus
+@.raw\_minus@>
+{\parindent=6pc
+\item{Used threads:}
+ none
+}
+@*2 TH\_terminals\_phrase\_th --- Parse terminals vocabulary.
+\Linkeridxentryk{Parse terminals vocabulary.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{TH\_terminals\_phrase\_th}{1}
+@.TH\_terminals\_phrase\_th@>
+\Linkercalledthreads{TH\_lint\_balls}{2}
+@.TH\_lint\_balls@>
+\Linkercalledthreads{TH\_ws}{3}
+@.TH\_ws@>
+\Linkercalledthreads{TH\_c\_comments}{3}
+@.TH\_c\_comments@>
+\Linkercalledthreads{TH\_eol}{3}
+@.TH\_eol@>
+{\parindent=6pc
+\item{First set:}
+LR1\_questionable\_shift\_operator
+@.LR1\_questionable\_shift\_operator@>
+raw\_ht
+@.raw\_ht@>
+raw\_lf
+@.raw\_lf@>
+raw\_vt
+@.raw\_vt@>
+raw\_ff
+@.raw\_ff@>
+raw\_cr
+@.raw\_cr@>
+raw\_sp
+@.raw\_sp@>
+raw\_open\_bracket
+@.raw\_open\_bracket@>
+raw\_slash
+@.raw\_slash@>
+{\parindent=6pc
+\item{Used threads:}
+TH\_cweb\_or\_c\_k
+@.TH\_cweb\_or\_c\_k@>
+TH\_identifier
+@.TH\_identifier@>
+TH\_lint\_balls
+@.TH\_lint\_balls@>
+TH\_o2\_sdc
+@.TH\_o2\_sdc@>
+TH\_term\_def\_ph
+@.TH\_term\_def\_ph@>
+}
+@*2 TH\_terminal\_def\_symclass --- Lexer of ``sym-class'' keyword.
+\Linkeridxentryk{Lexer of ``sym-class'' keyword.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{TH\_terminal\_def\_symclass}{1}
+@.TH\_terminal\_def\_symclass@>
+{\parindent=6pc
+\item{First set:}
+raw\_s
+@.raw\_s@>
+{\parindent=6pc
+\item{Used threads:}
+ none
+}
+@*2 TH\_term\_def\_ph --- Parse a terminal symbol.
+\Linkeridxentryk{Parse a terminal symbol.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{TH\_term\_def\_ph}{1}
+@.TH\_term\_def\_ph@>
+\Linkercalledthreads{TH\_c\_string}{2}
+@.TH\_c\_string@>
+\Linkercalledthreads{TH\_identifier}{2}
+@.TH\_identifier@>
+{\parindent=6pc
+\item{First set:}
+raw\_dbl\_quote
+@.raw\_dbl\_quote@>
+raw\_A
+@.raw\_A@>
+raw\_B
+@.raw\_B@>
+raw\_C
+@.raw\_C@>
+raw\_D
+@.raw\_D@>
+raw\_E
+@.raw\_E@>
+raw\_F
+@.raw\_F@>
+raw\_G
+@.raw\_G@>
+raw\_H
+@.raw\_H@>
+raw\_I
+@.raw\_I@>
+raw\_J
+@.raw\_J@>
+raw\_K
+@.raw\_K@>
+raw\_L
+@.raw\_L@>
+raw\_M
+@.raw\_M@>
+raw\_N
+@.raw\_N@>
+raw\_O
+@.raw\_O@>
+raw\_P
+@.raw\_P@>
+raw\_Q
+@.raw\_Q@>
+raw\_R
+@.raw\_R@>
+raw\_S
+@.raw\_S@>
+raw\_T
+@.raw\_T@>
+raw\_U
+@.raw\_U@>
+raw\_V
+@.raw\_V@>
+raw\_W
+@.raw\_W@>
+raw\_X
+@.raw\_X@>
+raw\_Y
+@.raw\_Y@>
+raw\_Z
+@.raw\_Z@>
+raw\_a
+@.raw\_a@>
+raw\_b
+@.raw\_b@>
+raw\_c
+@.raw\_c@>
+raw\_d
+@.raw\_d@>
+raw\_e
+@.raw\_e@>
+raw\_f
+@.raw\_f@>
+raw\_g
+@.raw\_g@>
+raw\_h
+@.raw\_h@>
+raw\_i
+@.raw\_i@>
+raw\_j
+@.raw\_j@>
+raw\_k
+@.raw\_k@>
+raw\_l
+@.raw\_l@>
+raw\_m
+@.raw\_m@>
+raw\_n
+@.raw\_n@>
+raw\_o
+@.raw\_o@>
+raw\_p
+@.raw\_p@>
+raw\_q
+@.raw\_q@>
+raw\_r
+@.raw\_r@>
+raw\_s
+@.raw\_s@>
+raw\_t
+@.raw\_t@>
+raw\_u
+@.raw\_u@>
+raw\_v
+@.raw\_v@>
+raw\_w
+@.raw\_w@>
+raw\_x
+@.raw\_x@>
+raw\_y
+@.raw\_y@>
+raw\_z
+@.raw\_z@>
+{\parindent=6pc
+\item{Used threads:}
+TH\_c\_string
+@.TH\_c\_string@>
+TH\_cweb\_or\_c\_k
+@.TH\_cweb\_or\_c\_k@>
+TH\_identifier
+@.TH\_identifier@>
+TH\_lint\_balls
+@.TH\_lint\_balls@>
+TH\_o2\_sdc
+@.TH\_o2\_sdc@>
+TH\_t\_def\_delabort\_tags
+@.TH\_t\_def\_delabort\_tags@>
+TH\_terminal\_def\_symclass
+@.TH\_terminal\_def\_symclass@>
+}
+@*2 TH\_t\_def\_delabort\_tags --- AB AD grammar symbol tags recognizer.
+\Linkeridxentryk{AB AD grammar symbol tags recognizer.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{TH\_t\_def\_delabort\_tags}{1}
+@.TH\_t\_def\_delabort\_tags@>
+{\parindent=6pc
+\item{First set:}
+raw\_A
+@.raw\_A@>
+{\parindent=6pc
+\item{Used threads:}
+ none
+}
+@*2 TH\_T\_enum\_phrase\_th --- Parse ``T-enumeration'' construct: Time out sme$\ldots$ .
+\Linkeridxentryk{Parse ``T-enumeration'' construct: Time out smell the tullips.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{TH\_T\_enum\_phrase\_th}{1}
+@.TH\_T\_enum\_phrase\_th@>
+\Linkercalledthreads{TH\_lint\_balls}{2}
+@.TH\_lint\_balls@>
+\Linkercalledthreads{TH\_ws}{3}
+@.TH\_ws@>
+\Linkercalledthreads{TH\_c\_comments}{3}
+@.TH\_c\_comments@>
+\Linkercalledthreads{TH\_eol}{3}
+@.TH\_eol@>
+{\parindent=6pc
+\item{First set:}
+LR1\_questionable\_shift\_operator
+@.LR1\_questionable\_shift\_operator@>
+raw\_ht
+@.raw\_ht@>
+raw\_lf
+@.raw\_lf@>
+raw\_vt
+@.raw\_vt@>
+raw\_ff
+@.raw\_ff@>
+raw\_cr
+@.raw\_cr@>
+raw\_sp
+@.raw\_sp@>
+raw\_open\_bracket
+@.raw\_open\_bracket@>
+raw\_slash
+@.raw\_slash@>
+{\parindent=6pc
+\item{Used threads:}
+TH\_identifier
+@.TH\_identifier@>
+TH\_lint\_balls
+@.TH\_lint\_balls@>
+TH\_o2\_sdc
+@.TH\_o2\_sdc@>
+}
+@*2 TH\_unq\_str --- Unquoted string of characters: raw and basic.
+\Linkeridxentryk{Unquoted string of characters: raw and basic.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{TH\_unq\_str}{1}
+@.TH\_unq\_str@>
+{\parindent=6pc
+\item{First set:}
+LR1\_eolr
+@.LR1\_eolr@>
+LR1\_all\_shift\_operator
+@.LR1\_all\_shift\_operator@>
+{\parindent=6pc
+\item{Used threads:}
+ none
+}
+@*2 TH\_ws --- White space globber.
+\Linkeridxentryk{White space globber.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{TH\_ws}{1}
+@.TH\_ws@>
+{\parindent=6pc
+\item{First set:}
+raw\_ht
+@.raw\_ht@>
+raw\_vt
+@.raw\_vt@>
+raw\_ff
+@.raw\_ff@>
+raw\_sp
+@.raw\_sp@>
+{\parindent=6pc
+\item{Used threads:}
+ none
+}
+@*2 TH\_xc\_str --- No escape sequence check: accept all characters between dbl$\ldots$ .
+\Linkeridxentryk{No escape sequence check: accept all characters between dbl. quoted string.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{TH\_xc\_str}{1}
+@.TH\_xc\_str@>
+{\parindent=6pc
+\item{First set:}
+raw\_dbl\_quote
+@.raw\_dbl\_quote@>
+{\parindent=6pc
+\item{Used threads:}
+ none
+}
+@*2 Ccweave\_fsm\_sdc --- Write out cweave fsm directives sentences.
+\Linkeridxentryk{Write out cweave fsm directives sentences.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{Ccweave\_fsm\_sdc}{1}
+@.Ccweave\_fsm\_sdc@>
+{\parindent=6pc
+\item{First set:}
+T\_user\_declaration
+@.T\_user\_declaration@>
+T\_user\_prefix\_declaration
+@.T\_user\_prefix\_declaration@>
+T\_user\_suffix\_declaration
+@.T\_user\_suffix\_declaration@>
+T\_constructor
+@.T\_constructor@>
+T\_destructor
+@.T\_destructor@>
+T\_op
+@.T\_op@>
+T\_failed
+@.T\_failed@>
+T\_user\_implementation
+@.T\_user\_implementation@>
+T\_user\_imp\_tbl
+@.T\_user\_imp\_tbl@>
+T\_user\_imp\_sym
+@.T\_user\_imp\_sym@>
+{\parindent=6pc
+\item{Used threads:}
+ none
+}
+@*2 Ccweave\_lhs\_sdc --- Write out cweave rule's lhs directives sentences.
+\Linkeridxentryk{Write out cweave rule's lhs directives sentences}
+\Linkercalledthreadstitle
+\Linkercalledthreads{Ccweave\_lhs\_sdc}{1}
+@.Ccweave\_lhs\_sdc@>
+{\parindent=6pc
+\item{First set:}
+T\_arbitrator\_code
+@.T\_arbitrator\_code@>
+T\_user\_declaration
+@.T\_user\_declaration@>
+T\_constructor
+@.T\_constructor@>
+T\_destructor
+@.T\_destructor@>
+T\_op
+@.T\_op@>
+T\_user\_implementation
+@.T\_user\_implementation@>
+{\parindent=6pc
+\item{Used threads:}
+ none
+}
+@*2 Ccweave\_sdc --- Write out cweave subrule's sdc irectives sentences.
+\Linkeridxentryk{Write out cweave subrule's sdc irectives sentences}
+\Linkercalledthreadstitle
+\Linkercalledthreads{Ccweave\_sdc}{1}
+@.Ccweave\_sdc@>
+{\parindent=6pc
+\item{First set:}
+T\_arbitrator\_code
+@.T\_arbitrator\_code@>
+T\_user\_declaration
+@.T\_user\_declaration@>
+T\_user\_prefix\_declaration
+@.T\_user\_prefix\_declaration@>
+T\_user\_suffix\_declaration
+@.T\_user\_suffix\_declaration@>
+T\_constructor
+@.T\_constructor@>
+T\_destructor
+@.T\_destructor@>
+T\_op
+@.T\_op@>
+T\_user\_implementation
+@.T\_user\_implementation@>
+T\_user\_imp\_tbl
+@.T\_user\_imp\_tbl@>
+T\_user\_imp\_sym
+@.T\_user\_imp\_sym@>
+{\parindent=6pc
+\item{Used threads:}
+ none
+}
+@*2 Ccweave\_T\_sdc --- Write out cweave Terminals' sdc directives.
+\Linkeridxentryk{Write out cweave Terminals' sdc directives.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{Ccweave\_T\_sdc}{1}
+@.Ccweave\_T\_sdc@>
+{\parindent=6pc
+\item{First set:}
+T\_user\_declaration
+@.T\_user\_declaration@>
+T\_constructor
+@.T\_constructor@>
+T\_destructor
+@.T\_destructor@>
+T\_op
+@.T\_op@>
+T\_user\_implementation
+@.T\_user\_implementation@>
+{\parindent=6pc
+\item{Used threads:}
+ none
+}
+@*2 Ccweb\_put\_k\_into\_ph --- Extract CWEB comments.
+\Linkeridxentryk{Extract CWEB comments.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{Ccweb\_put\_k\_into\_ph}{1}
+@.Ccweb\_put\_k\_into\_ph@>
+{\parindent=6pc
+\item{First set:}
+T\_fsm\_phrase
+@.T\_fsm\_phrase@>
+T\_parallel\_parser\_phrase
+@.T\_parallel\_parser\_phrase@>
+T\_enum\_phrase
+@.T\_enum\_phrase@>
+T\_terminals\_phrase
+@.T\_terminals\_phrase@>
+T\_error\_symbols\_phrase
+@.T\_error\_symbols\_phrase@>
+T\_lr1\_k\_phrase
+@.T\_lr1\_k\_phrase@>
+T\_rc\_phrase
+@.T\_rc\_phrase@>
+T\_rules\_phrase
+@.T\_rules\_phrase@>
+{\parindent=6pc
+\item{Used threads:}
+ none
+}
+@*2 Cenumerate\_grammar --- Dump aid: Enumerate grammar's components.
+\Linkeridxentryk{Dump aid: Enumerate grammar's components}
+\Linkercalledthreadstitle
+\Linkercalledthreads{Cenumerate\_grammar}{1}
+@.Cenumerate\_grammar@>
+{\parindent=6pc
+\item{First set:}
+rule\_def
+@.rule\_def@>
+{\parindent=6pc
+\item{Used threads:}
+ none
+}
+@*2 Cenumerate\_T\_alphabet --- Enumerate grammar's terminal symbols:
+a 0 and $\ldots$ .
+\Linkeridxentryk{Enumerate grammar's terminal symbols:
+a 0 and a 1, ... the oracle for parsing lookups.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{Cenumerate\_T\_alphabet}{1}
+@.Cenumerate\_T\_alphabet@>
+{\parindent=6pc
+\item{First set:}
+{\parindent=6pc
+\item{Used threads:}
+ none
+}
+@*2 Cepsilon\_rules --- Determine whether rules are epsilon, derive T, or are p$\ldots$ .
+\Linkeridxentryk{Determine whether rules are epsilon, derive T, or are pathological.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{Cepsilon\_rules}{1}
+@.Cepsilon\_rules@>
+{\parindent=6pc
+\item{First set:}
+rule\_def
+@.rule\_def@>
+{\parindent=6pc
+\item{Used threads:}
+ none
+}
+@*2 Cerr\_symbols\_ph --- Dispatcher to parse ``error-symbols'' vocabulary.
+\Linkeridxentryk{Dispatcher to parse ``error-symbols'' vocabulary.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{Cerr\_symbols\_ph}{1}
+@.Cerr\_symbols\_ph@>
+\Linkercalledthreads{TH\_err\_symbols\_ph\_th}{2}
+@.TH\_err\_symbols\_ph\_th@>
+\Linkercalledthreads{TH\_lint\_balls}{3}
+@.TH\_lint\_balls@>
+\Linkercalledthreads{TH\_ws}{4}
+@.TH\_ws@>
+\Linkercalledthreads{TH\_c\_comments}{4}
+@.TH\_c\_comments@>
+\Linkercalledthreads{TH\_eol}{4}
+@.TH\_eol@>
+{\parindent=6pc
+\item{First set:}
+LR1\_questionable\_shift\_operator
+@.LR1\_questionable\_shift\_operator@>
+{\parindent=6pc
+\item{Used threads:}
+TH\_err\_symbols\_ph\_th
+@.TH\_err\_symbols\_ph\_th@>
+}
+@*2 Ceval\_phrases --- Evaluate parse phrase sequencer:
+ as i use a top / down$\ldots$ .
+\Linkeridxentryk{Evaluate parse phrase sequencer:
+ as i use a top / down approach to dispatching the various phrases.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{Ceval\_phrases}{1}
+@.Ceval\_phrases@>
+{\parindent=6pc
+\item{First set:}
+LR1\_questionable\_shift\_operator
+@.LR1\_questionable\_shift\_operator@>
+LR1\_eog
+@.LR1\_eog@>
+T\_fsm\_phrase
+@.T\_fsm\_phrase@>
+{\parindent=6pc
+\item{Used threads:}
+ none
+}
+@*2 Cfsc\_file --- \Olinker's ``fsc'' control file parser.
+\Linkeridxentryk{\Olinker's ``fsc'' control file parser.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{Cfsc\_file}{1}
+@.Cfsc\_file@>
+{\parindent=6pc
+\item{First set:}
+LR1\_questionable\_shift\_operator
+@.LR1\_questionable\_shift\_operator@>
+T\_transitive
+@.T\_transitive@>
+{\parindent=6pc
+\item{Used threads:}
+ none
+}
+@*2 Cfsm\_phrase --- Dispatcher to parse ``fsm'' construct.
+\Linkeridxentryk{Dispatcher to parse ``fsm'' construct.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{Cfsm\_phrase}{1}
+@.Cfsm\_phrase@>
+\Linkercalledthreads{TH\_fsm\_phrase\_th}{2}
+@.TH\_fsm\_phrase\_th@>
+\Linkercalledthreads{TH\_lint\_balls}{3}
+@.TH\_lint\_balls@>
+\Linkercalledthreads{TH\_ws}{4}
+@.TH\_ws@>
+\Linkercalledthreads{TH\_c\_comments}{4}
+@.TH\_c\_comments@>
+\Linkercalledthreads{TH\_eol}{4}
+@.TH\_eol@>
+{\parindent=6pc
+\item{First set:}
+LR1\_questionable\_shift\_operator
+@.LR1\_questionable\_shift\_operator@>
+{\parindent=6pc
+\item{Used threads:}
+TH\_fsm\_phrase\_th
+@.TH\_fsm\_phrase\_th@>
+}
+@*2 Cla\_expr --- Parse the lookahead expression after chaffe removed.
+\Linkeridxentryk{Parse the lookahead expression after chaffe removed.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{Cla\_expr}{1}
+@.Cla\_expr@>
+{\parindent=6pc
+\item{First set:}
+LR1\_all\_shift\_operator
+@.LR1\_all\_shift\_operator@>
+T\_in\_stbl
+@.T\_in\_stbl@>
+rule\_in\_stbl
+@.rule\_in\_stbl@>
+{\parindent=6pc
+\item{Used threads:}
+ none
+}
+@*2 Cla\_expr\_lexical --- Lexer: 2nd stage lexing for lookahead: stripper...
+\Linkeridxentryk{Lexer: 2nd stage lexing for lookahead: stripper...}
+\Linkercalledthreadstitle
+\Linkercalledthreads{Cla\_expr\_lexical}{1}
+@.Cla\_expr\_lexical@>
+{\parindent=6pc
+\item{First set:}
+LR1\_all\_shift\_operator
+@.LR1\_all\_shift\_operator@>
+raw\_plus
+@.raw\_plus@>
+raw\_minus
+@.raw\_minus@>
+T\_c\_literal
+@.T\_c\_literal@>
+T\_c\_string
+@.T\_c\_string@>
+T\_identifier
+@.T\_identifier@>
+{\parindent=6pc
+\item{Used threads:}
+ none
+}
+@*2 Clinker\_pass3 --- Lexer: constructing tokens for \olinker parsing stage.
+\Linkeridxentryk{Lexer: constructing tokens for \olinker parsing stage.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{Clinker\_pass3}{1}
+@.Clinker\_pass3@>
+\Linkercalledthreads{TH\_linker\_id}{2}
+@.TH\_linker\_id@>
+\Linkercalledthreads{TH\_lint\_balls}{2}
+@.TH\_lint\_balls@>
+\Linkercalledthreads{TH\_ws}{3}
+@.TH\_ws@>
+\Linkercalledthreads{TH\_c\_comments}{3}
+@.TH\_c\_comments@>
+\Linkercalledthreads{TH\_eol}{3}
+@.TH\_eol@>
+{\parindent=6pc
+\item{First set:}
+LR1\_questionable\_shift\_operator
+@.LR1\_questionable\_shift\_operator@>
+{\parindent=6pc
+\item{Used threads:}
+TH\_angled\_string
+@.TH\_angled\_string@>
+TH\_c\_string
+@.TH\_c\_string@>
+TH\_linker\_id
+@.TH\_linker\_id@>
+TH\_linker\_preamble\_code
+@.TH\_linker\_preamble\_code@>
+TH\_lint\_balls
+@.TH\_lint\_balls@>
+}
+@*2 Clink\_cleanser --- Lexer: \olinker's cleanser from
+ previous lexing to re$\ldots$ .
+\Linkeridxentryk{Lexer: \olinker's cleanser from
+ previous lexing to remove chaffe before parsing stage.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{Clink\_cleanser}{1}
+@.Clink\_cleanser@>
+\Linkercalledthreads{TH\_ws}{2}
+@.TH\_ws@>
+\Linkercalledthreads{TH\_c\_comments}{2}
+@.TH\_c\_comments@>
+\Linkercalledthreads{TH\_c\_string}{2}
+@.TH\_c\_string@>
+\Linkercalledthreads{TH\_linker\_id}{2}
+@.TH\_linker\_id@>
+\Linkercalledthreads{TH\_int\_no}{2}
+@.TH\_int\_no@>
+\Linkercalledthreads{TH\_eol}{2}
+@.TH\_eol@>
+\Linkercalledthreads{TH\_bad\_char\_set}{2}
+@.TH\_bad\_char\_set@>
+{\parindent=6pc
+\item{First set:}
+LR1\_eog
+@.LR1\_eog@>
+LR1\_all\_shift\_operator
+@.LR1\_all\_shift\_operator@>
+{\parindent=6pc
+\item{Used threads:}
+TH\_bad\_char\_set
+@.TH\_bad\_char\_set@>
+TH\_c\_comments
+@.TH\_c\_comments@>
+TH\_c\_string
+@.TH\_c\_string@>
+TH\_eol
+@.TH\_eol@>
+TH\_int\_no
+@.TH\_int\_no@>
+TH\_linker\_id
+@.TH\_linker\_id@>
+TH\_ws
+@.TH\_ws@>
+}
+@*2 Clr1\_k\_phrase --- Dispatcher to parse ``lrk-symbols'' construct.
+\Linkeridxentryk{Dispatcher to parse ``lrk-symbols'' construct.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{Clr1\_k\_phrase}{1}
+@.Clr1\_k\_phrase@>
+\Linkercalledthreads{TH\_lr1\_k\_phrase\_th}{2}
+@.TH\_lr1\_k\_phrase\_th@>
+\Linkercalledthreads{TH\_lint\_balls}{3}
+@.TH\_lint\_balls@>
+\Linkercalledthreads{TH\_ws}{4}
+@.TH\_ws@>
+\Linkercalledthreads{TH\_c\_comments}{4}
+@.TH\_c\_comments@>
+\Linkercalledthreads{TH\_eol}{4}
+@.TH\_eol@>
+{\parindent=6pc
+\item{First set:}
+LR1\_questionable\_shift\_operator
+@.LR1\_questionable\_shift\_operator@>
+{\parindent=6pc
+\item{Used threads:}
+TH\_lr1\_k\_phrase\_th
+@.TH\_lr1\_k\_phrase\_th@>
+}
+@*2 Cmpost\_output --- Output grammar rules railroad diagrams for mpost that cw$\ldots$ .
+\Linkeridxentryk{Output grammar rules railroad diagrams for mpost that cweb program uses.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{Cmpost\_output}{1}
+@.Cmpost\_output@>
+{\parindent=6pc
+\item{First set:}
+T\_grammar\_phrase
+@.T\_grammar\_phrase@>
+{\parindent=6pc
+\item{Used threads:}
+ none
+}
+@*2 Co2\_err\_hdlr --- Logic sequencer: Print out errors from \O2.
+\Linkeridxentryk{Logic sequencer: Print out errors from \O2.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{Co2\_err\_hdlr}{1}
+@.Co2\_err\_hdlr@>
+{\parindent=6pc
+\item{First set:}
+LR1\_eog
+@.LR1\_eog@>
+LR1\_all\_shift\_operator
+@.LR1\_all\_shift\_operator@>
+Err\_nested\_files\_exceeded
+@.Err\_nested\_files\_exceeded@>
+Err\_no\_end\_of\_code
+@.Err\_no\_end\_of\_code@>
+Err\_no\_filename
+@.Err\_no\_filename@>
+Err\_bad\_filename
+@.Err\_bad\_filename@>
+Err\_bad\_cmd\_lne\_opt
+@.Err\_bad\_cmd\_lne\_opt@>
+Err\_bad\_int\_no
+@.Err\_bad\_int\_no@>
+Err\_bad\_int\_no\_range
+@.Err\_bad\_int\_no\_range@>
+Err\_no\_int\_present
+@.Err\_no\_int\_present@>
+Err\_bad\_eos
+@.Err\_bad\_eos@>
+Err\_bad\_esc
+@.Err\_bad\_esc@>
+Err\_comment\_overrun
+@.Err\_comment\_overrun@>
+Err\_bad\_char
+@.Err\_bad\_char@>
+Err\_bad\_univ\_seq
+@.Err\_bad\_univ\_seq@>
+T\_file\_inclusion
+@.T\_file\_inclusion@>
+{\parindent=6pc
+\item{Used threads:}
+ none
+}
+@*2 Co2\_lcl\_opts --- \O2's command line options dispatcher.
+\Linkeridxentryk{\O2's command line options dispatcher.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{Co2\_lcl\_opts}{1}
+@.Co2\_lcl\_opts@>
+\Linkercalledthreads{TH\_ws}{2}
+@.TH\_ws@>
+\Linkercalledthreads{TH\_c\_comments}{2}
+@.TH\_c\_comments@>
+\Linkercalledthreads{TH\_eol}{2}
+@.TH\_eol@>
+\Linkercalledthreads{TH\_unq\_str}{2}
+@.TH\_unq\_str@>
+\Linkercalledthreads{TH\_xc\_str}{2}
+@.TH\_xc\_str@>
+\Linkercalledthreads{TH\_o2\_lcl\_opt}{2}
+@.TH\_o2\_lcl\_opt@>
+{\parindent=6pc
+\item{First set:}
+LR1\_questionable\_shift\_operator
+@.LR1\_questionable\_shift\_operator@>
+{\parindent=6pc
+\item{Used threads:}
+TH\_c\_comments
+@.TH\_c\_comments@>
+TH\_eol
+@.TH\_eol@>
+TH\_o2\_lcl\_opt
+@.TH\_o2\_lcl\_opt@>
+TH\_unq\_str
+@.TH\_unq\_str@>
+TH\_ws
+@.TH\_ws@>
+TH\_xc\_str
+@.TH\_xc\_str@>
+}
+@*2 Co2\_linker\_opts --- \Olinker's Command line options parser.
+\Linkeridxentryk{\Olinker's Command line options parser.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{Co2\_linker\_opts}{1}
+@.Co2\_linker\_opts@>
+\Linkercalledthreads{TH\_ws}{2}
+@.TH\_ws@>
+\Linkercalledthreads{TH\_c\_comments}{2}
+@.TH\_c\_comments@>
+\Linkercalledthreads{TH\_eol}{2}
+@.TH\_eol@>
+\Linkercalledthreads{TH\_unq\_str}{2}
+@.TH\_unq\_str@>
+\Linkercalledthreads{TH\_xc\_str}{2}
+@.TH\_xc\_str@>
+{\parindent=6pc
+\item{First set:}
+LR1\_questionable\_shift\_operator
+@.LR1\_questionable\_shift\_operator@>
+{\parindent=6pc
+\item{Used threads:}
+TH\_c\_comments
+@.TH\_c\_comments@>
+TH\_eol
+@.TH\_eol@>
+TH\_unq\_str
+@.TH\_unq\_str@>
+TH\_ws
+@.TH\_ws@>
+TH\_xc\_str
+@.TH\_xc\_str@>
+}
+@*2 Cparallel\_parser\_phrase --- Dispather to parse grammar's ``parallel-parse$\ldots$ .
+\Linkeridxentryk{Dispather to parse grammar's ``parallel-parser'' construct.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{Cparallel\_parser\_phrase}{1}
+@.Cparallel\_parser\_phrase@>
+\Linkercalledthreads{TH\_parallel\_parser\_ph\_th}{2}
+@.TH\_parallel\_parser\_ph\_th@>
+\Linkercalledthreads{TH\_lint\_balls}{3}
+@.TH\_lint\_balls@>
+\Linkercalledthreads{TH\_ws}{4}
+@.TH\_ws@>
+\Linkercalledthreads{TH\_c\_comments}{4}
+@.TH\_c\_comments@>
+\Linkercalledthreads{TH\_eol}{4}
+@.TH\_eol@>
+{\parindent=6pc
+\item{First set:}
+LR1\_questionable\_shift\_operator
+@.LR1\_questionable\_shift\_operator@>
+{\parindent=6pc
+\item{Used threads:}
+TH\_parallel\_parser\_ph\_th
+@.TH\_parallel\_parser\_ph\_th@>
+}
+@*2 Cpass3 --- \O2's lexer constructing tokens for syntax parser stage.
+\Linkeridxentryk{\O2's lexer constructing tokens for syntax parser stage.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{Cpass3}{1}
+@.Cpass3@>
+\Linkercalledthreads{TH\_ws}{2}
+@.TH\_ws@>
+\Linkercalledthreads{TH\_identifier}{2}
+@.TH\_identifier@>
+\Linkercalledthreads{TH\_cweb\_or\_c\_k}{2}
+@.TH\_cweb\_or\_c\_k@>
+\Linkercalledthreads{TH\_eol}{2}
+@.TH\_eol@>
+\Linkercalledthreads{TH\_bad\_char\_set}{2}
+@.TH\_bad\_char\_set@>
+{\parindent=6pc
+\item{First set:}
+LR1\_questionable\_shift\_operator
+@.LR1\_questionable\_shift\_operator@>
+LR1\_eog
+@.LR1\_eog@>
+raw\_at\_sign
+@.raw\_at\_sign@>
+{\parindent=6pc
+\item{Used threads:}
+TH\_bad\_char\_set
+@.TH\_bad\_char\_set@>
+TH\_cweb\_or\_c\_k
+@.TH\_cweb\_or\_c\_k@>
+TH\_eol
+@.TH\_eol@>
+TH\_identifier
+@.TH\_identifier@>
+TH\_ws
+@.TH\_ws@>
+}
+@*2 Cprt\_sr\_elements --- Print the subrule's symbol string.
+\Linkeridxentryk{Print the subrule's symbol string.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{Cprt\_sr\_elements}{1}
+@.Cprt\_sr\_elements@>
+{\parindent=6pc
+\item{First set:}
+T\_subrule\_def
+@.T\_subrule\_def@>
+{\parindent=6pc
+\item{Used threads:}
+ none
+}
+@*2 Cprt\_xrefs\_docs --- Output xref doc ---
+``first set'' per rule, and refe$\ldots$ .
+\Linkeridxentryk{Output xref doc ---
+``first set'' per rule, and referenced symbols.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{Cprt\_xrefs\_docs}{1}
+@.Cprt\_xrefs\_docs@>
+{\parindent=6pc
+\item{First set:}
+rule\_def
+@.rule\_def@>
+{\parindent=6pc
+\item{Used threads:}
+ none
+}
+@*2 Crc\_phrase --- Dispatcher to parse raw character vocabulary.
+\Linkeridxentryk{Dispatcher to parse raw character vocabulary.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{Crc\_phrase}{1}
+@.Crc\_phrase@>
+\Linkercalledthreads{TH\_rc\_phrase\_th}{2}
+@.TH\_rc\_phrase\_th@>
+\Linkercalledthreads{TH\_lint\_balls}{3}
+@.TH\_lint\_balls@>
+\Linkercalledthreads{TH\_ws}{4}
+@.TH\_ws@>
+\Linkercalledthreads{TH\_c\_comments}{4}
+@.TH\_c\_comments@>
+\Linkercalledthreads{TH\_eol}{4}
+@.TH\_eol@>
+{\parindent=6pc
+\item{First set:}
+LR1\_questionable\_shift\_operator
+@.LR1\_questionable\_shift\_operator@>
+{\parindent=6pc
+\item{Used threads:}
+TH\_rc\_phrase\_th
+@.TH\_rc\_phrase\_th@>
+}
+@*2 Crules\_phrase --- Dispatcher to parse the grammar's rules.
+\Linkeridxentryk{Dispatcher to parse the grammar's rules.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{Crules\_phrase}{1}
+@.Crules\_phrase@>
+\Linkercalledthreads{TH\_rules\_phrase\_th}{2}
+@.TH\_rules\_phrase\_th@>
+\Linkercalledthreads{TH\_ws}{3}
+@.TH\_ws@>
+\Linkercalledthreads{TH\_cweb\_or\_c\_k}{3}
+@.TH\_cweb\_or\_c\_k@>
+\Linkercalledthreads{TH\_eol}{3}
+@.TH\_eol@>
+{\parindent=6pc
+\item{First set:}
+LR1\_questionable\_shift\_operator
+@.LR1\_questionable\_shift\_operator@>
+{\parindent=6pc
+\item{Used threads:}
+TH\_rules\_phrase\_th
+@.TH\_rules\_phrase\_th@>
+}
+@*2 Crules\_use\_cnt --- Optimization: Count ``rules used''
+ to lower new / de$\ldots$ .
+\Linkeridxentryk{Optimization: Count ``rules used''
+ to lower new / delete rule cycles while parsing.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{Crules\_use\_cnt}{1}
+@.Crules\_use\_cnt@>
+{\parindent=6pc
+\item{First set:}
+rule\_def
+@.rule\_def@>
+{\parindent=6pc
+\item{Used threads:}
+ none
+}
+@*2 Cterminals\_phrase --- Dispatcher to parse the terminals alphabet.
+\Linkeridxentryk{Dispatcher to parse the terminals alphabet.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{Cterminals\_phrase}{1}
+@.Cterminals\_phrase@>
+\Linkercalledthreads{TH\_terminals\_phrase\_th}{2}
+@.TH\_terminals\_phrase\_th@>
+\Linkercalledthreads{TH\_lint\_balls}{3}
+@.TH\_lint\_balls@>
+\Linkercalledthreads{TH\_ws}{4}
+@.TH\_ws@>
+\Linkercalledthreads{TH\_c\_comments}{4}
+@.TH\_c\_comments@>
+\Linkercalledthreads{TH\_eol}{4}
+@.TH\_eol@>
+{\parindent=6pc
+\item{First set:}
+LR1\_questionable\_shift\_operator
+@.LR1\_questionable\_shift\_operator@>
+{\parindent=6pc
+\item{Used threads:}
+TH\_terminals\_phrase\_th
+@.TH\_terminals\_phrase\_th@>
+}
+@*2 Ctest\_components --- Tester: lexical stage constructing tokens for syntax $\ldots$ .
+\Linkeridxentryk{Tester: lexical stage constructing tokens for syntax parser.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{Ctest\_components}{1}
+@.Ctest\_components@>
+\Linkercalledthreads{TH\_o2\_code\_end}{2}
+@.TH\_o2\_code\_end@>
+\Linkercalledthreads{TH\_angled\_string}{2}
+@.TH\_angled\_string@>
+\Linkercalledthreads{TH\_bad\_char\_set}{2}
+@.TH\_bad\_char\_set@>
+\Linkercalledthreads{TH\_c\_comments}{2}
+@.TH\_c\_comments@>
+\Linkercalledthreads{TH\_c\_literal}{2}
+@.TH\_c\_literal@>
+\Linkercalledthreads{TH\_c\_string}{2}
+@.TH\_c\_string@>
+\Linkercalledthreads{TH\_dbl\_colon}{2}
+@.TH\_dbl\_colon@>
+\Linkercalledthreads{TH\_eol}{2}
+@.TH\_eol@>
+\Linkercalledthreads{TH\_esc\_seq}{2}
+@.TH\_esc\_seq@>
+\Linkercalledthreads{TH\_identifier}{2}
+@.TH\_identifier@>
+\Linkercalledthreads{TH\_int\_no}{2}
+@.TH\_int\_no@>
+\Linkercalledthreads{TH\_ws}{2}
+@.TH\_ws@>
+{\parindent=6pc
+\item{First set:}
+LR1\_eog
+@.LR1\_eog@>
+LR1\_all\_shift\_operator
+@.LR1\_all\_shift\_operator@>
+{\parindent=6pc
+\item{Used threads:}
+TH\_angled\_string
+@.TH\_angled\_string@>
+TH\_bad\_char\_set
+@.TH\_bad\_char\_set@>
+TH\_c\_comments
+@.TH\_c\_comments@>
+TH\_c\_literal
+@.TH\_c\_literal@>
+TH\_c\_string
+@.TH\_c\_string@>
+TH\_dbl\_colon
+@.TH\_dbl\_colon@>
+TH\_eol
+@.TH\_eol@>
+TH\_esc\_seq
+@.TH\_esc\_seq@>
+TH\_identifier
+@.TH\_identifier@>
+TH\_int\_no
+@.TH\_int\_no@>
+TH\_o2\_code\_end
+@.TH\_o2\_code\_end@>
+TH\_ws
+@.TH\_ws@>
+}
+@*2 Ct\_alphabet --- Parse Linker's t-alphabet language.
+\Linkeridxentryk{Parse Linker's t-alphabet language.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{Ct\_alphabet}{1}
+@.Ct\_alphabet@>
+{\parindent=6pc
+\item{First set:}
+LR1\_questionable\_shift\_operator
+@.LR1\_questionable\_shift\_operator@>
+T\_T\_alphabet
+@.T\_T\_alphabet@>
+{\parindent=6pc
+\item{Used threads:}
+ none
+}
+@*2 CT\_enum\_phrase --- Dispatcher to parse T-enumeration construct.
+\Linkeridxentryk{Dispatcher to parse T-enumeration construct.}
+\Linkercalledthreadstitle
+\Linkercalledthreads{CT\_enum\_phrase}{1}
+@.CT\_enum\_phrase@>
+\Linkercalledthreads{TH\_T\_enum\_phrase\_th}{2}
+@.TH\_T\_enum\_phrase\_th@>
+\Linkercalledthreads{TH\_lint\_balls}{3}
+@.TH\_lint\_balls@>
+\Linkercalledthreads{TH\_ws}{4}
+@.TH\_ws@>
+\Linkercalledthreads{TH\_c\_comments}{4}
+@.TH\_c\_comments@>
+\Linkercalledthreads{TH\_eol}{4}
+@.TH\_eol@>
+{\parindent=6pc
+\item{First set:}
+LR1\_questionable\_shift\_operator
+@.LR1\_questionable\_shift\_operator@>
+{\parindent=6pc
+\item{Used threads:}
+TH\_T\_enum\_phrase\_th
+@.TH\_T\_enum\_phrase\_th@>
+}
+@** First set control file (fsc) listing.\fbreak
+File : ``/yacco2/compiler/grammars/yacco2.fsc''\fbreak
+\let\setuplistinghook = \relax
+\listing{"/yacco2/compiler/grammars/yacco2.fsc"}
+
+@** Index.
diff --git a/web/yacco2/o2linker/o2linker_externs.cpp b/web/yacco2/o2linker/o2linker_externs.cpp
new file mode 100644
index 0000000000..f9767979ba
--- /dev/null
+++ b/web/yacco2/o2linker/o2linker_externs.cpp
@@ -0,0 +1,54 @@
+/*7:*/
+//line 83 "./o2linker_externs.w"
+
+/*6:*/
+//line 80 "./o2linker_externs.w"
+
+#include "o2linker_externs.h"
+/*:6*/
+//line 84 "./o2linker_externs.w"
+
+/*8:*/
+//line 89 "./o2linker_externs.w"
+
+
+yacco2::AST*CWEB_MARKER(0);
+
+/*:8*//*10:*/
+//line 112 "./o2linker_externs.w"
+
+extern
+void
+LINKER_PARSE_CMD_LINE
+(const char*Cmd_file,std::string&Ctrl_file,yacco2::TOKEN_GAGGLE&Errors)
+{
+using namespace NS_yacco2_err_symbols;
+using namespace yacco2;
+tok_can<std::ifstream> Cmd1_tokens(Cmd_file);
+if(Cmd1_tokens.file_ok()==NO){
+yacco2::Delete_tokens(Cmd1_tokens.container());
+CAbs_lr1_sym*sym= new Err_bad_filename(Cmd_file);
+sym->set_external_file_id(1);
+sym->set_line_no(1);
+sym->set_pos_in_line(1);
+Errors.push_back(*sym);
+return;
+}
+
+using namespace NS_o2_linker_opts;
+TOKEN_GAGGLE linker_options_tokens;
+Co2_linker_opts opts_fsm;
+Parser options(opts_fsm,&Cmd1_tokens,&linker_options_tokens,0,&Errors,0,0);
+options.parse();
+yacco2::Delete_tokens(Cmd1_tokens.container());
+if(Errors.empty()!=YES)return;
+Ctrl_file+= opts_fsm.file_to_compile_;
+return;
+}
+
+/*:10*/
+//line 85 "./o2linker_externs.w"
+
+
+
+/*:7*/
diff --git a/web/yacco2/o2linker/o2linker_externs.h b/web/yacco2/o2linker/o2linker_externs.h
new file mode 100644
index 0000000000..5f8905428a
--- /dev/null
+++ b/web/yacco2/o2linker/o2linker_externs.h
@@ -0,0 +1,32 @@
+/*4:*/
+//line 55 "./o2linker_externs.w"
+
+#ifndef o2linker_externs_
+#define o2linker_externs_ 1
+
+//line 58 "./o2linker_externs.w"
+
+/*5:*/
+//line 63 "./o2linker_externs.w"
+
+#include "globals.h"
+#include "o2linker_types.h"
+#include "yacco2_stbl.h"
+#include "o2_linker_opts.h"
+#include "linker_pass3.h"
+
+extern STBL_T_ITEMS_type STBL_T_ITEMS;
+extern void GET_CMD_LINE(int argc,char*argv[]
+,const char*File,yacco2::TOKEN_GAGGLE&Errors);
+extern void LINKER_PARSE_CMD_LINE(const char*Fsc
+,std::string&Cntl_file,yacco2::TOKEN_GAGGLE&Errors);
+extern void DUMP_ERROR_QUEUE(yacco2::TOKEN_GAGGLE&Errors);
+extern const char*DATE_AND_TIME();
+extern void XLATE_SYMBOLS_FOR_cweave(const char*Sym_to_xlate,char*Xlated_sym);
+extern yacco2::AST*CWEB_MARKER;
+/*:5*/
+//line 59 "./o2linker_externs.w"
+
+#endif
+
+/*:4*/
diff --git a/web/yacco2/o2linker/o2linker_externs.w b/web/yacco2/o2linker/o2linker_externs.w
new file mode 100644
index 0000000000..33fff26142
--- /dev/null
+++ b/web/yacco2/o2linker/o2linker_externs.w
@@ -0,0 +1,147 @@
+@q file: o2linker_externs.w@>
+@q% Copyright Dave Bone 1998 - 2015@>
+@q% /*@>
+@q% This Source Code Form is subject to the terms of the Mozilla Public@>
+@q% License, v. 2.0. If a copy of the MPL was not distributed with this@>
+@q% file, You can obtain one at http://mozilla.org/MPL/2.0/.@>
+@q% */@>
+@q% This file is part of YACC02 compiler/compiler project.@>
+
+\input "eplain"
+\input "supp-pdf"
+\input "/usr/local/yacco2/diagrams/o2mac.tex"
+%\tracingall=1
+%\tracingall=1
+%\tracingmacros=1
+%\tracingcommands=2
+@i "/usr/local/yacco2/license.w"
+@** Summary Linker External parse routines.\fbreak
+These are the various procedures that parse \Yacco2's grammar language
+and emit the grammar's c++ code
+and tex document with mpost generated diagrams.
+Each language construct has its appropriate external procedure that houses
+the monolithic grammar to start the parse.
+There is no namespace used to contain these routines as I felt that this was overkill.
+As this is a closed system, their grammars are not universal and
+cannot be re-cycled for others.
+Their only outside value are in teaching examples on ``how to skin a cat'' or is it
+``how to parse a lion?''...
+
+External routines ratatouille:\fbreak
+\ptindent{|o2linker_externs.w| - cweb generator file}
+\ptindent{|o2linker_externs.h| - header file}
+\ptindent{|o2linker_externs.cpp| - implementation}
+
+Dependency files from other Yacco2 sub-systems:\fbreak
+\ptindent{|yacco2.h| - basic definitions used by Yacco2}
+\ptindent{|yacco2_T_enumeration.h| - terminal enumeration for Yacco2's terminal grammar alphabet}
+\ptindent{|yacco2_err_symbols.h| - error terminal definitions from Yacco2's grammar alphabet}
+\ptindent{|yacco2_characters.h| - raw character definitions from Yacco2's grammar alphabet}
+\ptindent{|yacco2_k_symbols.h| - constant meta terminal defs from Yacco2's grammar alphabet}
+\ptindent{|yacco2_terminals.h| - regular terminal definitions from Yacco2's grammar alphabet}
+\ptindent{|*.h| - assorted grammar definitions for Yacco2's parsing}
+\ptindent{|yacco2_stbl.h| - symbol table defnitions}
+
+External procedures and other globals:\fbreak
+\ptindent{|LINKER_PARSE_CMD_LINE|}
+
+@** Global definitions, External parse routines for Yacco2.\fbreak
+\def\ptindent#1{\line{\hskip.5in{#1}\hfill}}
+\def\fbreak{\hfill\break}
+\def\wildcard{$\vert$+$\vert$}
+\def\parallelop{$\vert\vert\vert$}
+
+@ Create header file.
+@(o2linker_externs.h@>=
+#ifndef o2linker_externs_
+#define o2linker_externs_ 1
+@h
+@<Files for header@>;
+#endif
+
+@*2 Files for header.
+@<Files for header@>=
+#include "globals.h"
+#include "o2linker_types.h"
+#include "yacco2_stbl.h"
+#include "o2_linker_opts.h"
+#include "linker_pass3.h"
+
+extern STBL_T_ITEMS_type STBL_T_ITEMS;
+extern void GET_CMD_LINE(int argc, char* argv[]
+ ,const char* File,yacco2::TOKEN_GAGGLE& Errors);
+extern void LINKER_PARSE_CMD_LINE(const char* Fsc
+ ,std::string& Cntl_file,yacco2::TOKEN_GAGGLE& Errors);
+extern void DUMP_ERROR_QUEUE(yacco2::TOKEN_GAGGLE& Errors);
+extern const char* DATE_AND_TIME();
+extern void XLATE_SYMBOLS_FOR_cweave(const char* Sym_to_xlate,char* Xlated_sym);
+extern yacco2::AST*CWEB_MARKER;
+@ Include Header file.
+@<Include Header file@>=
+#include "o2linker_externs.h"
+@ Yacco2 external routines blueprint. Output of the code.
+@(o2linker_externs.cpp@>=
+@<Include Header file@>;
+@<accrue source for emit@>;
+
+
+@ Accrue source for emit.
+@<accrue source for emit@>=
+
+yacco2::AST*CWEB_MARKER(0);
+
+@** Local o2linker routines.\fbreak
+
+
+@*2 Linker Parse command line: |LINKER_PARSE_CMD_LINE|.\fbreak
+The parameters have been extracted from the program
+run environment and placed into Linker's holding file.
+The routine is suitable for public consumption if
+a filename parameter is needed.
+
+
+Constraints:\fbreak
+ \ptindent{ip1: Linker's holding file containing the command line to compile}
+ \ptindent{ip2: Extracted fsc file to compile}
+ \ptindent{ip3: Error container for generated errors}
+
+Errors:\fbreak
+\ptindent{1) bad filename}
+\ptindent{2) parameters errors}
+
+@<accrue source for emit@>+=
+extern
+void
+LINKER_PARSE_CMD_LINE@/
+ (const char* Cmd_file,std::string& Ctrl_file,yacco2::TOKEN_GAGGLE& Errors)@/
+{
+ using namespace NS_yacco2_err_symbols;
+ using namespace yacco2;
+ tok_can<std::ifstream> Cmd1_tokens(Cmd_file);
+ if(Cmd1_tokens.file_ok() == NO){
+ yacco2::Delete_tokens(Cmd1_tokens.container());
+ CAbs_lr1_sym* sym = new Err_bad_filename(Cmd_file);
+ sym->set_external_file_id(1);
+ sym->set_line_no(1);
+ sym->set_pos_in_line(1);
+ Errors.push_back(*sym);
+ return;
+ }
+
+ using namespace NS_o2_linker_opts;
+ TOKEN_GAGGLE linker_options_tokens;
+ Co2_linker_opts opts_fsm;
+ Parser options(opts_fsm,&Cmd1_tokens,&linker_options_tokens,0,&Errors,0,0);
+ options.parse();
+ yacco2::Delete_tokens(Cmd1_tokens.container());
+ if(Errors.empty() != YES) return;
+ Ctrl_file += opts_fsm.file_to_compile_;
+ return;
+}
+
+@** Bric-a-brac.\fbreak
+
+@** Index.
+
+
+
diff --git a/web/yacco2/o2linker/o2linker_types.h b/web/yacco2/o2linker/o2linker_types.h
new file mode 100644
index 0000000000..70765a179c
--- /dev/null
+++ b/web/yacco2/o2linker/o2linker_types.h
@@ -0,0 +1,142 @@
+/*2:*/
+#line 41 "./o2linker_types.w"
+
+#ifndef o2linker_types_
+#define o2linker_types_ 1
+/*3:*/
+#line 52 "./o2linker_types.w"
+
+#define CWEAVE_TITLE_LIMIT 75
+#define RESERVE_FIXED_NO_THREADS 1024
+#define NO_BITS_PER_SET_PARTITION 8
+#define ACCEPT_FILTER true
+#define BYPASS_FILTER false
+#define Success true
+#define Failure false
+#define Nested_file_cnt_limit 15
+#define O2_library_file "yacco2.h"
+#define Yacco2_holding_file "yacco2cmd.tmp"
+#define Linker_holding_file "linkercmd.tmp"
+#define Max_buf_size 2*1024
+#define Max_cweb_item_size 10*1024
+/*:3*/
+#line 44 "./o2linker_types.w"
+;
+/*4:*/
+#line 67 "./o2linker_types.w"
+
+typedef int Voc_ENO;
+typedef int RULE_ENO;
+
+/*:4*//*5:*/
+#line 71 "./o2linker_types.w"
+
+typedef std::set<int> INT_SET_type;
+/*:5*//*6:*/
+#line 73 "./o2linker_types.w"
+
+typedef INT_SET_type::iterator INT_SET_ITER_type;
+/*:6*//*7:*/
+#line 75 "./o2linker_types.w"
+
+typedef std::vector<INT_SET_type> INT_SET_LIST_type;
+/*:7*//*8:*/
+#line 77 "./o2linker_types.w"
+
+typedef INT_SET_LIST_type::iterator INT_SET_LIST_ITER_type;
+/*:8*//*9:*/
+#line 79 "./o2linker_types.w"
+
+typedef std::map<int,std::string> INT_STR_MAP_type;
+/*:9*//*10:*/
+#line 81 "./o2linker_types.w"
+
+typedef INT_STR_MAP_type::iterator INT_STR_MAP_ITER_type;
+/*:10*//*11:*/
+#line 83 "./o2linker_types.w"
+
+typedef std::set<std::string*> STR_SET_type;
+/*:11*//*12:*/
+#line 85 "./o2linker_types.w"
+
+typedef STR_SET_type::iterator STR_SET_ITER_type;
+/*:12*//*13:*/
+#line 87 "./o2linker_types.w"
+
+typedef std::map<NS_yacco2_terminals::T_in_stbl*,STR_SET_type> T_IN_STBL_SET_STR_MAP_type;
+/*:13*//*14:*/
+#line 89 "./o2linker_types.w"
+
+typedef T_IN_STBL_SET_STR_MAP_type::iterator T_IN_STBL_SET_STR_MAP_ITER_type;
+/*:14*//*15:*/
+#line 91 "./o2linker_types.w"
+
+typedef int Voc_ENO;
+/*:15*//*16:*/
+#line 93 "./o2linker_types.w"
+
+typedef int RULE_ENO;
+/*:16*//*17:*/
+#line 95 "./o2linker_types.w"
+
+typedef int T_ENO;
+/*:17*//*18:*/
+#line 98 "./o2linker_types.w"
+
+typedef std::set<T_in_stbl*> T_IN_STBL_SET_type;
+/*:18*//*19:*/
+#line 101 "./o2linker_types.w"
+
+typedef T_IN_STBL_SET_type::iterator T_IN_STBL_SET_ITER_type;
+/*:19*//*20:*/
+#line 103 "./o2linker_types.w"
+
+typedef vector<T_ENO> T_COUNT_type;
+/*:20*//*21:*/
+#line 105 "./o2linker_types.w"
+
+typedef T_COUNT_type::iterator T_COUNT_ITER_type;
+/*:21*//*22:*/
+#line 107 "./o2linker_types.w"
+
+typedef vector<T_in_stbl*> STBL_T_ITEMS_type;
+/*:22*//*23:*/
+#line 109 "./o2linker_types.w"
+
+typedef STBL_T_ITEMS_type::iterator STBL_T_ITEMS_ITER_type;
+/*:23*//*24:*/
+#line 111 "./o2linker_types.w"
+
+typedef std::map<int,int> BIT_MAP_type;
+/*:24*//*25:*/
+#line 113 "./o2linker_types.w"
+
+typedef BIT_MAP_type::iterator BIT_MAP_ITER_type;
+
+/*:25*/
+#line 45 "./o2linker_types.w"
+;
+/*26:*/
+#line 117 "./o2linker_types.w"
+
+struct prt_called_thread_list_ast_functor:public Type_AST_functor{
+functor_result_type operator()(yacco2::ast_base_stack*Stk_env);
+typedef void(*PFF)(AST*,std::ofstream*,int);
+prt_called_thread_list_ast_functor(PFF Func);
+void o_file(std::ofstream*Ow_linker_file);
+void reset_cnt();
+private:
+yacco2::ast_base_stack*stk_env_;
+yacco2::INT idx_;
+yacco2::AST*cnode_;
+yacco2::ast_base_stack::s_rec*srec_;
+PFF prt_funct_;
+yacco2::INT cnt_;
+std::ofstream*ow_linker_file_;
+};
+/*:26*/
+#line 46 "./o2linker_types.w"
+;
+#endif
+
+/*:2*/
diff --git a/web/yacco2/o2linker/o2linker_types.w b/web/yacco2/o2linker/o2linker_types.w
new file mode 100644
index 0000000000..99cd42dca7
--- /dev/null
+++ b/web/yacco2/o2linker/o2linker_types.w
@@ -0,0 +1,133 @@
+@q file: o2linker_types.w@>
+@q% Copyright Dave Bone 1998 - 2015@>
+@q% /*@>
+@q% This Source Code Form is subject to the terms of the Mozilla Public@>
+@q% License, v. 2.0. If a copy of the MPL was not distributed with this@>
+@q% file, You can obtain one at http://mozilla.org/MPL/2.0/.@>
+@q% */@>
+\input "eplain"
+\input "supp-pdf"
+\input"/usr/local/yacco2/diagrams/o2mac.tex"
+@*2 Global definitions and files.\fbreak
+Basic preamble include files used by all others.
+@(globals.h@>=
+// file: globals.h
+// prelude files using yacco2: for o2, o2linker utilities
+#ifndef globals_h__
+#define globals_h__ 1
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+
+#include "yacco2.h"
+#include "yacco2_T_enumeration.h"
+#include "yacco2_err_symbols.h"
+#include "yacco2_characters.h"
+#include "yacco2_k_symbols.h"
+#include "yacco2_terminals.h"
+using namespace std;
+using namespace NS_yacco2_T_enum;
+using namespace NS_yacco2_k_symbols;
+using namespace NS_yacco2_terminals;
+using namespace yacco2;
+#endif
+
+@*3 ``o2linker\_types'' header file of common set of definitions and structures.\fbreak
+``o2linker\_types.h'' file is a common set of definitions
+and structures used by ``o2linker\_externs.w''
+external routines.
+Contains definitions and type-defs.
+@(o2linker_types.h@>=
+#ifndef o2linker_types_
+#define o2linker_types_ 1
+@<defines@>;
+@<Type defs@>;
+@<Structure defs@>;
+#endif
+
+@ Definitions for O2 and my external routines --- ``yacco2\_extn.w''.\fbreak
+As i'm writing directly out to a file, the use of the ctangle macro directive
+displays its displeasure so i'm using the direct c code route.
+@<defines@>=
+#define CWEAVE_TITLE_LIMIT 75
+#define RESERVE_FIXED_NO_THREADS 1024
+#define NO_BITS_PER_SET_PARTITION 8
+#define ACCEPT_FILTER true
+#define BYPASS_FILTER false
+#define Success true
+#define Failure false
+#define Nested_file_cnt_limit 15
+#define O2_library_file "yacco2.h"
+#define Yacco2_holding_file "yacco2cmd.tmp"
+#define Linker_holding_file "linkercmd.tmp"
+#define Max_buf_size 2*1024
+#define Max_cweb_item_size 10*1024
+@ Typedef definitions.
+@<Type defs@>=
+typedef int Voc_ENO;
+typedef int RULE_ENO;
+
+@ @<Type defs@>+=
+typedef std::set<int> INT_SET_type;
+@ @<Type defs@>+=
+typedef INT_SET_type::iterator INT_SET_ITER_type;
+@ @<Type defs@>+=
+typedef std::vector< INT_SET_type> INT_SET_LIST_type;
+@ @<Type defs@>+=
+typedef INT_SET_LIST_type::iterator INT_SET_LIST_ITER_type;
+@ @<Type defs@>+=
+typedef std::map<int,std::string> INT_STR_MAP_type;
+@ @<Type defs@>+=
+typedef INT_STR_MAP_type::iterator INT_STR_MAP_ITER_type;
+@ @<Type defs@>+=
+typedef std::set<std::string*> STR_SET_type;
+@ @<Type defs@>+=
+typedef STR_SET_type::iterator STR_SET_ITER_type;
+@ @<Type defs@>+=
+typedef std::map<NS_yacco2_terminals::T_in_stbl*,STR_SET_type > T_IN_STBL_SET_STR_MAP_type;
+@ @<Type defs@>+=
+typedef T_IN_STBL_SET_STR_MAP_type::iterator T_IN_STBL_SET_STR_MAP_ITER_type;
+@ @<Type defs@>+=
+typedef int Voc_ENO;
+@ @<Type defs@>+=
+typedef int RULE_ENO;
+@ @<Type defs@>+=
+typedef int T_ENO;
+@
+@<Type defs@>+=
+typedef std::set<T_in_stbl*> T_IN_STBL_SET_type;
+@
+@<Type defs@>+=
+typedef T_IN_STBL_SET_type::iterator T_IN_STBL_SET_ITER_type;
+@ @<Type defs@>+=
+typedef vector<T_ENO> T_COUNT_type;
+@ @<Type defs@>+=
+typedef T_COUNT_type::iterator T_COUNT_ITER_type;
+@ @<Type defs@>+=
+typedef vector<T_in_stbl*> STBL_T_ITEMS_type;
+@ @<Type defs@>+=
+typedef STBL_T_ITEMS_type::iterator STBL_T_ITEMS_ITER_type;
+@ @<Type defs@>+=
+typedef std::map<int,int> BIT_MAP_type;
+@ @<Type defs@>+=
+typedef BIT_MAP_type::iterator BIT_MAP_ITER_type;
+
+@*2 |prt_called_thread_list_ast_functor|.\fbreak
+@<Structure defs@>+=
+struct prt_called_thread_list_ast_functor :public Type_AST_functor{
+ functor_result_type operator()(yacco2::ast_base_stack* Stk_env);
+ typedef void (*PFF)(AST*,std::ofstream*,int);
+ prt_called_thread_list_ast_functor(PFF Func);
+ void o_file(std::ofstream* Ow_linker_file);
+ void reset_cnt();
+ private:@/
+ yacco2::ast_base_stack* stk_env_;
+ yacco2::INT idx_;
+ yacco2::AST* cnode_;
+ yacco2::ast_base_stack::s_rec* srec_;
+ PFF prt_funct_;
+ yacco2::INT cnt_;
+ std::ofstream* ow_linker_file_;
+};
+
diff --git a/web/yacco2/o2linker/pms.w b/web/yacco2/o2linker/pms.w
new file mode 100644
index 0000000000..e12c8c5441
--- /dev/null
+++ b/web/yacco2/o2linker/pms.w
@@ -0,0 +1,38 @@
+@q file: pms.w@>
+@q% Copyright Dave Bone 1998 - 2015@>
+@q% /*@>
+@q% This Source Code Form is subject to the terms of the Mozilla Public@>
+@q% License, v. 2.0. If a copy of the MPL was not distributed with this@>
+@q% file, You can obtain one at http://mozilla.org/MPL/2.0/.@>
+@q% */@>
+@** PMS --- Post meta syndrome.\fbreak
+Post thoughts of improvement before using Linker.
+
+@ What happens when there are no threads to produce?.\fbreak
+Deal with iT?
+Sorry for the yelling...haha
+This is a legitimate situation.\fbreak
+
+So |THDS_STABLE__| and |T_ARRAY_HAVING_THD_IDS__| have NULL pointers emitted.
+This situation does not have to be checked for in Yacco2 parse library
+as there are no threads in the local state configuration to be tried.
+Yacco2 parsing checks to see if the ${\vert\vert\vert}$ symbol is present in the current
+state configuration before trying to parallel parse.\fbreak
+22 April 2005
+
+@ Passover on code.\fbreak
+Spring cleaning so put in those last gasp constraints. I know
+C++'s containers could be used to generate bit maps but...
+Enough of my rantings and mistrust on others software.
+So there's a hardcoded number of threads supported.
+The number of threads supported is |SPECULATIVE_NO_BIT_WORDS| *
+|BITS_PER_WORD|. Under current definitions this works out to 20*32 threads
+that can be gened. A bit of overkill but u never know who's out there.
+Now u can rant at me if this limit is surpassed. I would really
+like to know what u're doing to exceed this speed bump:
+Could be an interesting conversation. \fbreak
+24 Apr. 2005
+
+@ Add test suites.\fbreak
+25 Apr. 2005
+
diff --git a/web/yacco2/o2linker/prog.w b/web/yacco2/o2linker/prog.w
new file mode 100644
index 0000000000..38c728960c
--- /dev/null
+++ b/web/yacco2/o2linker/prog.w
@@ -0,0 +1,1134 @@
+@q file: prog.w@>
+@q% Copyright Dave Bone 1998 - 2015@>
+@q% /*@>
+@q% This Source Code Form is subject to the terms of the Mozilla Public@>
+@q% License, v. 2.0. If a copy of the MPL was not distributed with this@>
+@q% file, You can obtain one at http://mozilla.org/MPL/2.0/.@>
+@q% */@>
+@*2 External routines and globals.\fbreak
+General routines to get things going:\fbreak
+\ptindent{1) get control file and put into Linker's holding file}
+\ptindent{2) parse the command line}
+\ptindent{3) format errors}
+These are defined by including |o2_externs.h|.
+
+The globals are:\fbreak
+\ptindent{1) |Error_queue| --- global container of errors passed across all parsings}
+\ptindent{2) |GRAMMAR_DICTIONARY| --- thread container whose contents point into the symbol table}
+\ptindent{3) |T_DICTIONARY| --- terminal container whose contents point into the symbol table}
+\ptindent{4) |T_THREAD_ID_LIST| --- thread id list per terminal}
+\ptindent{5) |NO_OF_THREADS| --- found number of threads}
+\ptindent{6) |NO_WORDS_FOR_BIT_MAP| --- calculated number of words per thread bit map}
+\ptindent{7) |THREAD_ID_FS| --- first set per thread id}
+
+@<External rtns and ...@>=
+extern int NO_OF_THREADS;@/
+extern int NO_WORDS_FOR_BIT_MAP;
+
+@ Do we have errors?.
+Check that error queue for those errors.
+Note, |DUMP_ERROR_QUEUE| will also flush out
+ any launched threads for the good housekeeping or is it
+housetrained seal
+award? Trying to do my best in the realm of short lived winddowns.
+@<if error queue not empty then deal with posted errors@>=
+if(Error_queue.empty()!=true){
+ DUMP_ERROR_QUEUE(Error_queue);
+ return 1;
+}
+
+@** Local routines.\fbreak
+@*2 Parse linker control file.\fbreak
+Handcrafted file that gathers all the grammar control files together for the processing.
+Note the use of |tok_can<std::ifstream>| to read raw characters
+and produce tokens in just-in-time.
+@<parse linker control file@>=
+ cout << "Parse linker control file " << endl;
+ using namespace NS_linker_pass3;
+ tok_can<std::ifstream> cntl_file_tokens(cntl_file_name.c_str());
+ TOKEN_GAGGLE P3_tokens;
+ Clinker_pass3 linker_cntl_file_fsm;
+ Parser linker_cntl_file(linker_cntl_file_fsm,&cntl_file_tokens,&P3_tokens,0,&Error_queue,0,0);
+ linker_cntl_file.parse();
+ @<if error queue not empty then deal with posted errors@>;
+
+@*2 Parse T alphabet.\fbreak
+Ahh the terminal vocabulary. The symbol's position within the list
+is also its enumerate value starting from 0.
+The |T_alphabet| grammar places the terminal symbols into the symbol table
+as a 1:1 mapping, into
+the |T_DICTIONARY| as a consolidated repository
+and into the |T_THREAD_ID_LIST|
+which is the terminal to thread list relationship used
+to quickly determine if the current token has the potential to run as a thread.
+Each thread contains its first set list squirreled away in thread\_attributes's |list_of_Ts_|.
+
+@<parse T alphabet@>=
+cout << "Parse alphabet" << endl;
+using namespace NS_link_cleanser;
+tok_can<std::ifstream> T_file_tokens(linker_cntl_file_fsm.t_alphabet_filename_.c_str());
+TOKEN_GAGGLE cleanser_tokens;
+Clink_cleanser cleanser_fsm;
+Parser cleanser(cleanser_fsm,&T_file_tokens,&cleanser_tokens,0,&Error_queue,0,0);
+cleanser.parse();
+
+using namespace NS_t_alphabet;
+TOKEN_GAGGLE T_tokens;
+Ct_alphabet T_fsm;
+Parser T_pass3(T_fsm,&cleanser_tokens,&T_tokens,0,&Error_queue,0,0);
+T_pass3.parse();
+@<if error queue not empty then deal with posted errors@>;
+
+@*2 Parse fsc files.\fbreak
+Digest those fsc files. Burp. Better that than the other end.
+Now for a chiro for the stretched stomach muscles.
+The |fsc_file| grammar puts the digested grammar's fsc content into
+the symbol table of thread attribute's object and its reference into
+the |GRAMMAR_DICTIONARY|.
+@<parse fsc files@>=
+cout << "Parse fsc files" << endl;
+TOKEN_GAGGLE cleanser_fsc_tokens;
+TOKEN_GAGGLE fsc_file_output_tokens;
+std::vector<std::string>::iterator ii = linker_cntl_file_fsm.grammars_fsc_files_.begin();
+std::vector<std::string>::iterator iie = linker_cntl_file_fsm.grammars_fsc_files_.end();
+for(;ii!=iie;++ii){
+ tok_can<std::ifstream> T_fsc_file_tokens(ii->c_str());
+ Clink_cleanser cleanser_fsc;
+ Parser fsc_cleanser(cleanser_fsc,&T_fsc_file_tokens
+ ,&cleanser_fsc_tokens,0,&Error_queue,0,0);
+ fsc_cleanser.parse();
+ @<if error queue not empty then deal with posted errors@>;
+
+ using namespace NS_fsc_file;
+ Cfsc_file fsc_file_fsm;
+ Parser fsc_file_pass(fsc_file_fsm,&cleanser_fsc_tokens
+ ,&fsc_file_output_tokens,0,&Error_queue,0,0);
+ fsc_file_pass.parse();
+ @<if error queue not empty then deal with posted errors@>;
+ cleanser_fsc_tokens.clear();
+ fsc_file_output_tokens.clear();
+}
+ @<if error queue not empty then deal with posted errors@>;
+
+@*2 |load_linkkw_into_tbl|.\fbreak
+ These are the keywords
+ from all the languages to be parsed.
+ So why the loading up of keywords? Speed.
+ |linker_id| does a symbol table lookup for \olinker.
+ So where ever appropriate like the
+ ``first set control'' files, normal boundary parsing can take place.
+ There is your lexical grammar that discriminates characters into
+ tokens like keywords, comments followed by
+ a separate syntax grammar to process the language structure.
+ See comments in Yacco2's external document regarding the reason for
+ the kludge.
+@<accrue linker code@>+=
+void load_linkkw_into_tbl(yacco2::CAbs_lr1_sym* Kw){
+ using namespace yacco2_stbl;
+ T_sym_tbl_report_card report_card;
+ KCHARP kwkey = Kw->id();
+ if(*kwkey == '#')++kwkey;// kludge: bypass 1st char eg "$\#$fsm"
+ kw_in_stbl* kw = new kw_in_stbl(Kw);
+ add_sym_to_stbl(report_card,*kwkey,*kw,table_entry::defed,table_entry::keyword);
+ kw->stbl_idx(report_card.pos_);
+}
+
+void load_linkkws_into_tbl()@/
+{
+ cout << "Load linker's keywords " << endl;
+ load_linkkw_into_tbl(new T_transitive);
+ load_linkkw_into_tbl(new T_grammar_name);
+ load_linkkw_into_tbl(new T_name_space);
+ load_linkkw_into_tbl(new T_thread_name);
+ load_linkkw_into_tbl(new T_fsm_comments);
+ load_linkkw_into_tbl(new T_monolithic);
+ load_linkkw_into_tbl(new T_file_name);
+ load_linkkw_into_tbl(new T_no_of_T);
+ load_linkkw_into_tbl(new T_list_of_native_first_set_terminals);
+ load_linkkw_into_tbl(new T_end_list_of_native_first_set_terminals);
+ load_linkkw_into_tbl(new T_list_of_transitive_threads);
+ load_linkkw_into_tbl(new T_end_list_of_transitive_threads);
+ load_linkkw_into_tbl(new T_list_of_used_threads);
+ load_linkkw_into_tbl(new T_end_list_of_used_threads);
+ load_linkkw_into_tbl(new T_T_alphabet);
+ load_linkkw_into_tbl(new T_end_T_alphabet);
+ load_linkkw_into_tbl(new T_file_of_T_alphabet);
+ load_linkkw_into_tbl(new T_emitfile);
+ load_linkkw_into_tbl(new T_preamble);
+ load_linkkw_into_tbl(new T_end_preamble);
+}
+
+
+@*2 Verify that all threads used are defined.\fbreak
+ Simple check! Just
+sequentially read the |GRAMMAR_DICTIONARY| whose elements are pointers to their
+symbol table registry where the entry is not ``defined'' but referenced by some
+transitive call list.
+The loop just pours the rogues into the error queue and uses the
+token co-ordinates that created the entry as ``used'' for the error message.
+This allows the error dump to pinpoint the source file and specific line that
+referenced the rogue thread.
+Correction is to add the missing grammar to the control file list or
+correct the grammar that issued the thread call.
+ @<post verify that there are no threads ``used'' and not ``defined''@>=
+ std::vector<table_entry*>::iterator th_i = GRAMMAR_DICTIONARY.begin();@/
+ std::vector<table_entry*>::iterator th_ie = GRAMMAR_DICTIONARY.end();@/
+ for(;th_i != th_ie;++th_i){
+ table_entry* tbl_entry = *th_i;
+
+ if(tbl_entry->defined_ == true) continue;
+ CAbs_lr1_sym* sym = new Err_bad_th_in_list;
+ sym->set_who_created("linker.w",__LINE__);
+
+ @=thread_attributes*th_goodies= ((th_in_stbl*)tbl_entry->symbol_)->thread_in_stbl();@>@/
+ sym->set_rc(*th_goodies);
+ Error_queue.push_back(*sym);
+ }
+ @<if error queue not empty then deal with posted errors@>;
+
+@** Sort thread dictionary.\fbreak
+The grammars are divided into 2 types:\fbreak
+\ptindent{1) monolithic --- stand alone grammars}
+\ptindent{2) called threads}
+
+
+To facilitate the emitted code,
+the following partial order is imposed on the fully qualified name (FQN) of the grammar
+composed of the grammar's namespace
+and name separated by ``::'': for example, |NS_eol::TH_eol|. This is the calling handle of
+the thread when used with the ${\vert\vert\vert}$ statement.
+The partial order is divided into 2 parts --- threads followed by standalone
+grammars:\fbreak
+\ptindent{thread vs thread --- lexicographical order on ``thread name'' only}
+\ptindent{thread vs mono --- thread less than mono grammar}
+\ptindent{mono vs thread --- thread less than mono grammar}
+\ptindent{mono vs mono --- lexicographical order on FQN}
+The order defines explicitly the enumerate value assigned to each thread starting from 0.
+The standalone grammars (monolithic) are not part of the thread stable that gets emitted.
+@<accrue linker code@>+=
+bool sort_threads_criteria(const table_entry* P1,const table_entry* P2){
+ @=th_in_stbl*th_tbl1= (th_in_stbl*)P1->symbol_;@> @/
+ @=th_in_stbl*th_tbl2= (th_in_stbl*)P2->symbol_;@> @/
+ thread_attributes* p1 = th_tbl1->thread_in_stbl();
+ thread_attributes* p2 = th_tbl2->thread_in_stbl();
+ int len_a = p1->thread_name_->c_string()->size();
+ int len_b = p2->thread_name_->c_string()->size();
+ string ucase_a;
+ for(int x=0;x<len_a;++x){
+ ucase_a += toupper((*p1->thread_name_->c_string())[x]) ;
+ }
+ string ucase_b;
+ for(int x=0;x<len_b;++x){
+ ucase_b += toupper((*p2->thread_name_->c_string())[x]) ;
+ }
+ if(len_a < len_b){
+ for(int x = len_a+1;x <=len_b;++x) ucase_a += ' ';
+ }else{
+ for(int x = len_b+1;x <=len_a;++x) ucase_b += ' ';
+ }
+ int result;
+ if(p1->monolithic_ == 'n'){// a:thread
+ if(p2->monolithic_ == 'n'){// a:thread b:thread
+ result = strcmp(ucase_a.c_str(),ucase_b.c_str());
+ if(result < 0) return true;// a less b
+ return false;// a gt b
+ }
+ return true;// a:thread b:mono; a less b
+ }
+ if(p2->monolithic_ == 'n'){// a:mono b:thread
+ return false;// a gt b
+ }
+ // a:mono b:mono changed to the thread name instead of fqn
+ int len_fqna = p1->thread_name_->c_string()->size();
+ int len_fqnb = p2->thread_name_->c_string()->size();
+ string ucase_fqna;
+ for(int x=0;x<len_fqna;++x){
+ ucase_fqna += toupper((*p1->thread_name_->c_string())[x]);
+ }
+ string ucase_fqnb;
+ for(int x=0;x<len_fqnb;++x){
+ ucase_fqnb += toupper((*p2->thread_name_->c_string())[x]);
+ }
+ if(len_fqna < len_fqnb){
+ for(int x = len_fqna+1;x <=len_fqnb;++x) ucase_fqna += ' ';
+ }else{
+ for(int x = len_fqnb+1;x <=len_fqna;++x) ucase_fqnb += ' ';
+ }
+ result = strcmp(ucase_fqna.c_str(),ucase_fqnb.c_str());
+ if(result < 0 ) return true;// a less b
+ return false;// a gt b
+}
+
+@*2 Sort uses template algorithm.
+@<sort thread dictionary@>=
+ cout << "Sort thread dictionary" << endl;
+ stable_sort(GRAMMAR_DICTIONARY.begin(),GRAMMAR_DICTIONARY.end(),sort_threads_criteria);
+
+@*2 Dump sorted dictionary.\fbreak
+Not another reality show? Yupp.
+@<dump sorted dictionary@>=
+yacco2::lrclog << "Sorted thread dictionary" << GRAMMAR_DICTIONARY.size()<< std::endl;
+ std::vector<table_entry*>::iterator dth_i = GRAMMAR_DICTIONARY.begin();@/
+ std::vector<table_entry*>::iterator dth_ie = GRAMMAR_DICTIONARY.end();@/
+ int pos(-1);
+ for(;dth_i != dth_ie;++dth_i){
+ ++pos;
+ table_entry* tbl_entry = *dth_i;
+ @=thread_attributes*th_goodies= ((th_in_stbl*)tbl_entry->symbol_)->thread_in_stbl();@>@/
+yacco2::lrclog << "tbl entry*: "
+<< tbl_entry << " th_goodies*: " << th_goodies
+<< " " << pos << ":" << th_goodies->th_enum_
+<< " mono: " << th_goodies->monolithic_
+ << " thread name: " << th_goodies->thread_name_->c_string()->c_str()
+ << " FQN: " << th_goodies->fully_qualified_th_name_.c_str()
+ << " K: " << th_goodies->fsm_comments_->c_string()->c_str()
+ << std::endl;
+ }
+
+@*2 Count and re-align threads enumerate values to sorted position.\fbreak
+The |NO_OF_THREADS| is calculated at the same time. It is used to indicate thread presence
+and the numbers of threads to emit.
+@<count and re-align threads enumerate values to sorted position@>=
+ std::vector<table_entry*>::iterator ri = GRAMMAR_DICTIONARY.begin();@/
+ std::vector<table_entry*>::iterator rie = GRAMMAR_DICTIONARY.end();@/
+ for(int p = -1;ri != rie;++ri){
+ ++p;
+ table_entry* tbl_entry = *ri;
+ @=thread_attributes*th_goodies= ((th_in_stbl*)tbl_entry->symbol_)->thread_in_stbl();@>@/
+ th_goodies->th_enum_ = p;
+ if(th_goodies->monolithic_ == 'n') ++NO_OF_THREADS;
+ }
+
+@ Check whether Linker has enough space to generate the thread bit maps.\fbreak
+See |Passover on code| for my comments.
+@<check whether Linker has enough space to gen thread bit maps: no throw up@>=
+int max_thds_supported = SPECULATIVE_NO_BIT_WORDS * BITS_PER_WORD;
+if(NO_OF_THREADS > max_thds_supported ){
+ char a[SMALL_BUFFER_4K];
+@.Error: not enough space for thread bit map manufacture!@>;
+ KCHARP msg =
+ "Error: not enough space for thread bit map manufacture!"
+ " # threads: %i, Linker's maximum no of threads supported: %i. \n"
+ " Please expand SPECULATIVE_NO_BIT_WORDS";
+ sprintf(a,msg,NO_OF_THREADS,max_thds_supported);
+ Yacco2_faulty_precondition(msg,__FILE__,__LINE__);
+ exit(1);
+}
+
+@** Thread graphs: first set generation.
+@*2 |Visit_graph|.
+@<External rtns and ...@>+=
+extern char Visit_graph[RESERVE_FIXED_NO_THREADS];
+@*3 Probagate ${\vert+\vert}$.\fbreak
+Not much to it. The ``all shift'' operator indicates all terminals.
+It is a wild token facility that eases the pain in using grammars.
+So, all terminals except some meta operators must be placed into
+the first set and the thread id against each terminal.
+
+To lower the \olinker document, the \ALLshift
+meta terminal representing all terminals substitutes ``eolr''
+in the thread's first set.
+It certainly makes for a cleaner document without the slug fest.
+@<probagate ${\vert+\vert}$@>=
+ INT_SET_ITER_type t_listi = Root_thread.fs_.find(LR1_EOLR);// substitute eolr
+ if(t_listi == Root_thread.fs_.end()){
+ Root_thread.fs_.insert(LR1_EOLR);
+ }
+
+ int no_of_T = T_DICTIONARY.size();// rel 1 instead of 0
+ for(int x=0;x<no_of_T;++x){
+ switch(x){
+ case LR1_QUESTIONABLE_SHIFT_OPERATOR:break;
+ case LR1_EOG:break;
+ case LR1_EOLR:continue;
+ case LR1_PARALLEL_OPERATOR:continue;
+ case LR1_REDUCE_OPERATOR:continue;
+ case LR1_INVISIBLE_SHIFT_OPERATOR:continue;
+ case LR1_ALL_SHIFT_OPERATOR:continue;
+ case LR1_FSET_TRANSIENCE_OPERATOR:continue;
+ default:break;
+ }
+ if(Visited_th.monolithic_ == 'n'){
+ INT_SET_type& th_list = T_THREAD_ID_LIST[x];
+ if(th_list.find(Visited_th.th_enum_) ==th_list.end()){
+ th_list.insert(Visited_th.th_enum_);
+ }
+ if(th_list.find(Root_thread_id) ==th_list.end()){
+ th_list.insert(Root_thread_id);
+ }
+ }
+ }
+
+@*3 Deal with threads having T in first set.\fbreak
+Please note that threads only are dealt with and not their standalone brethren.
+The root grammar is still traversed so that
+its called threads can be added to the list.
+
+Though the monolithic grammar is not launched by its first set,
+I included its first set calculations to verify my work.
+@<deal with threads having T in first set@>=
+ INT_SET_ITER_type t_listi = Root_thread.fs_.find(t_enum);
+ if(t_listi == Root_thread.fs_.end()){
+ Root_thread.fs_.insert(t_enum);
+ }
+if(Visited_th.monolithic_ == 'n'){
+ INT_SET_type& th_list = T_THREAD_ID_LIST[t_enum];@/
+ if(th_list.find(Visited_th.th_enum_) ==th_list.end()){
+ th_list.insert(Visited_th.th_enum_);
+ }
+ if(th_list.find(Root_thread_id) ==th_list.end()){
+ th_list.insert(Root_thread_id);
+ }
+}
+
+@*3 Associate native terminals with called thread.\fbreak
+For the moment until i can refine the thread's first set algorithm
+in \o2 that generates the Tes for ``list-of-native-first-set-terminals'',
+ i force ``attempting to run'' the threads
+having the \TRAshift in their first set across all Tes.
+There will be thread stutters in firing them up
+and then shuting them down when their true
+first set is outside of the current token.
+Remember these threads are fired up when they are in the
+being run grammar's current lr parse state.
+So the speed bump shouldn't be too big.
+
+@<associate native terminals with called thread@>=
+ std::vector<int>::iterator fi = Visited_th.list_of_Ts_.begin();@/
+ std::vector<int>::iterator fie = Visited_th.list_of_Ts_.end();@/
+ for(;fi!=fie;++fi){
+ int t_enum = *fi;
+ if(t_enum == LR1_ALL_SHIFT_OPERATOR){
+ @<probagate ${\vert+\vert}$@>;
+ }
+ @<deal with threads having T in first set@>;
+ }
+
+@*3 Process called thread's list.\fbreak
+Walk the list and recursively call that graph.
+@<process called thread's list@>=
+std::vector<thread_attributes*>::iterator li = Visited_th.list_of_transitive_threads_.begin();
+std::vector<thread_attributes*>::iterator lie = Visited_th.list_of_transitive_threads_.end();
+for(;li!=lie;++li){
+ thread_attributes* th_att = *li;
+lrclog << "------->process called thread's list thd: "
+<< th_att->thread_name_->c_string()->c_str()
+<< " for root thd id: " << Root_thread_id
+<< endl;
+ crt_fset_of_thread(*th_att,Root_thread_id,Root_thread);
+}
+
+@*2 |crt_fset_of_thread|.\fbreak
+Recursive procedure that chews gum, pats its stomach, and belches fire.\fbreak
+It traverses the called threads recursively to continue
+the association of the inherited terminals into their thread bit maps.
+Uses the |Visit_graph| to prevent self looping: whichever
+way u call it left or right recursion depending on your context ---
+cheers or bottoms-up.
+
+The |Root_thread_id| associates the starting thread id
+to the traversed called threads' first sets' terminals.
+Each thread is processed individually to associate itself
+with their called brethern's first sets.
+
+@<accrue linker code@>+=
+void crt_fset_of_thread
+ (thread_attributes& Visited_th
+ ,int Root_thread_id,thread_attributes& Root_thread){
+ if(Visit_graph[Visited_th.th_enum_] == 'y') return;
+ Visit_graph[Visited_th.th_enum_] = 'y';
+ @<associate native terminals with called thread@>;
+ @<process called thread's list@>;
+}
+
+@*2 Allocation space for |Visit_graph|.\fbreak
+Before, reserve allocated its space, now MS throws an error
+as |push_back| not done.
+@<allocation space for |Visit_graph|@>=
+ for(int vi = 0;vi<NO_OF_THREADS;++vi){
+ Visit_graph[vi] = 'n';
+ }
+
+@*2 Initialize |Visit_graph| to ``not visited''.\fbreak
+Each new thread having its final fist set's gened presets the graph.
+@<initialize |Visit_graph| to not visited@>=
+for(int vi = 0;vi<NO_OF_THREADS;++vi){
+ Visit_graph[vi] = 'n';
+}
+
+@*2 Generate those first sets.\fbreak
+Walk the what? u threads fulfull your first set destinies.
+Not very complex.
+A visit graph
+is built having its nodes equal in number to the threads
+in the |GRAMMAR_DICTIONARY|.
+Each node is initialized to ``not visited''.
+From here, it's just process each thread and visit its called threads to
+inherit their native terminals: Of course this is a transitive process.
+Sorry for the let down but there ain't much to it.
+
+A secondary graph of called threads per grammar is built so that
+ an overall linker document can be emitted with:\fbreak
+\ptindent{1) index of threads sorted by their name with its fsm's comments}
+\ptindent{2) followed by the monolithic grammars}
+\ptindent{3)) each grammar will have its called threads}
+@<generate threads final first sets@>=
+@<allocation space for |Visit_graph|@>;
+
+ std::vector<table_entry*>::iterator thi = GRAMMAR_DICTIONARY.begin();@/
+ std::vector<table_entry*>::iterator thie = GRAMMAR_DICTIONARY.end();@/
+ for(;thi != thie;++thi){// individually process each thread
+ @=th_in_stbl*th_tbl= (th_in_stbl*)(*thi)->symbol_;@> @/
+ thread_attributes* th_att = th_tbl->thread_in_stbl();
+ if(th_att->monolithic_ == 'n'){
+yacco2::lrclog << "thread being walked: "
+ <<th_att->thread_name_->c_string()->c_str() << " id: "
+<< th_att->th_enum_ << std::endl;
+ @<initialize |Visit_graph| to not visited@>;
+ crt_fset_of_thread(*th_att,th_att->th_enum_,*th_att);
+ }
+ }
+ thi = GRAMMAR_DICTIONARY.begin();@/
+ thie = GRAMMAR_DICTIONARY.end();@/
+ for(;thi != thie;++thi){// individually process each thread
+ @=th_in_stbl*th_tbl= (th_in_stbl*)(*thi)->symbol_;@> @/
+ thread_attributes* th_att = th_tbl->thread_in_stbl();
+ @<initialize |Visit_graph| to not visited@>;
+ crt_called_thread_graph(*th_att);
+ }
+
+@** Generate document for each grammar's called threads.\fbreak
+@*3 |crt_called_thread_list| and |walk_called_thread_list|.\fbreak
+Generate the call graph per thread for reporting purposes.
+@<accrue linker code@>+=
+void walk_called_thread_list(std::vector<thread_attributes*>& Thd_list,AST* Mother_thd_t){
+ if(Thd_list.begin() == Thd_list.end()) return;
+ std::vector<thread_attributes*>::iterator li = Thd_list.begin();
+ std::vector<thread_attributes*>::iterator lie = Thd_list.end();
+ for(;li!=lie;++li){
+ thread_attributes* th_att = *li;
+ if(Visit_graph[th_att->th_enum_] == 'y') continue;
+ Visit_graph[th_att->th_enum_] = 'y';
+ AST* called_t = new AST(*th_att);
+ AST::add_child_at_end(*Mother_thd_t,*called_t);
+ walk_called_thread_list(th_att->list_of_transitive_threads_,called_t);
+ }
+}
+
+@*3 |crt_called_thread_graph|.
+@<accrue linker code@>+=
+void crt_called_thread_graph(thread_attributes& Visited_th){
+ if(Visit_graph[Visited_th.th_enum_] == 'y') return;
+ Visit_graph[Visited_th.th_enum_] = 'y';
+ AST* mother_thd_t = new AST(Visited_th);
+ Visited_th.called_thread_graph_ = mother_thd_t;
+ walk_called_thread_list(Visited_th.list_of_transitive_threads_,mother_thd_t);
+}
+@*3 |gen_each_thread_s_referenced_threads|.
+@<accrue linker code@>+=
+void gen_each_grammar_s_referenced_threads(){
+ std::vector<table_entry*>::iterator thi = GRAMMAR_DICTIONARY.begin();@/
+ std::vector<table_entry*>::iterator thie = GRAMMAR_DICTIONARY.end();@/
+ for(;thi != thie;++thi){// individually process each thread
+ @=th_in_stbl*th_tbl= (th_in_stbl*)(*thi)->symbol_;@> @/
+ thread_attributes* th_att = th_tbl->thread_in_stbl();
+ @<initialize |Visit_graph| to not visited@>;
+ crt_called_thread_graph(*th_att);
+ }
+}
+@*1 Generate Linker's document.\fbreak
+A secondary graph of called threads per grammar is built so that
+ an overall linker document can be emitted with:\fbreak
+\ptindent{1) index of threads sorted by their name with its fsm's comments}
+\ptindent{2) followed by the monolithic grammars}
+\ptindent{3)) each grammar will have its ``called threads'' graph}
+
+@*4 Make grammar's contents cweaveable and output.
+@<make grammar's contents cweaveable and output@>=
+ XLATE_SYMBOLS_FOR_cweave(th_att->thread_name_->c_string()->c_str(),xlate_gfile);
+ XLATE_SYMBOLS_FOR_cweave(th_att->fsm_comments_->c_string()->c_str(),rebuild_comment);
+ strcat(fandk,xlate_gfile);
+ strcat(fandk," --- ");
+ strcat(fandk,rebuild_comment);
+ int fandk_len = strlen(fandk);
+ if(fandk_len < CWEAVE_TITLE_LIMIT){
+ if(fandk[fandk_len-1] != '.'){
+ strcat(fandk,".");
+ }
+ }else{
+ if(fandk_len == CWEAVE_TITLE_LIMIT){
+ if(fandk[CWEAVE_TITLE_LIMIT-1] != '.'){
+ strcat(fandk,".");
+ }
+ }else{
+ fandk[CWEAVE_TITLE_LIMIT] = (char)0;
+ strcat(fandk,"$\\ldots$ .");
+ }
+ }
+ int x = sprintf(big_buf_
+ ,w_grammar
+ ,fandk
+ );
+ ow_linker_file_.write(big_buf_,x);
+ ow_linker_file_ << std::endl;
+ x = sprintf(big_buf_
+ ,w_comments
+ ,rebuild_comment
+ );
+ ow_linker_file_.write(big_buf_,x);
+ ow_linker_file_ << std::endl;
+ x = sprintf(big_buf_
+ ,w_called_threads," "
+ );
+ ow_linker_file_.write(big_buf_,x);
+ ow_linker_file_ << std::endl;
+
+@*4 Output grammar's called threads list.
+@<output grammar's called threads list@>=
+ prt_called_thread_list_ast_functor prt_functr(&PRINT_CALLED_THREAD_LIST);
+ prt_functr.o_file(&ow_linker_file_);
+ ast_prefix pre(*th_att->called_thread_graph_,&prt_functr);
+ while (pre.base_stk_.cur_stk_rec() != 0){
+ pre.exec();
+ }
+
+@*4 Output grammar's used threads.
+@<output grammar's used threads@>=
+std::map<std::string, std::vector<std::string> >::iterator ti =
+ USED_THREADS_LIST.find(th_att->thread_name_->c_string()->c_str());
+ ow_linker_file_ << "{\\parindent=6pc" << endl;
+ ow_linker_file_ << "\\item{Used threads:}" << std::endl;
+ KCHARP used_threads =
+ "%s\n"
+ "@@.%s@@>";// xref entry
+ std::vector<std::string>& tt = ti->second;
+ std::vector<std::string>::iterator tti = tt.begin();
+ std::vector<std::string> ::iterator ttie= tt.end();
+ char xlate_thnm[Max_cweb_item_size];
+ for(;tti!=ttie;++tti){
+ XLATE_SYMBOLS_FOR_cweave(tti->c_str(),xlate_thnm);
+ int x = sprintf(big_buf_,used_threads,xlate_thnm,xlate_thnm);
+ ow_linker_file_.write(big_buf_,x);
+ ow_linker_file_ << std::endl;
+ }
+ if(ti->second.empty() == YES) ow_linker_file_ << " none" << endl;
+ ow_linker_file_ << "}" << endl;
+
+@*4 Output grammar's first set.\fbreak
+Go thru the set and map the T enum into its literal value.
+@<output grammar's first set@>=
+ ow_linker_file_ << "{\\parindent=6pc" << endl;
+ ow_linker_file_ << "\\item{First set:}" << std::endl;
+ KCHARP fs =
+ "%s\n"
+ "@@.%s@@>";// xref entry
+ INT_SET_ITER_type fsi = th_att->fs_.begin();
+ INT_SET_ITER_type fsie = th_att->fs_.end();
+ char xlate_tnm[Max_cweb_item_size];
+ for(;fsi!=fsie;++fsi){
+ int tenum = *fsi;
+ table_entry* t_entry = T_DICTIONARY[tenum];
+ tth_in_stbl* t_in_stbl = (tth_in_stbl*)t_entry->symbol_;
+ T_attributes * t_att = t_in_stbl->t_in_stbl();
+ XLATE_SYMBOLS_FOR_cweave(t_att->fully_qualified_T_name_.c_str(),xlate_tnm);
+ int x = sprintf(big_buf_,fs,xlate_tnm,xlate_tnm);
+ ow_linker_file_.write(big_buf_,x);
+ ow_linker_file_ << std::endl;
+ }
+
+@*3 Output preamble of document.
+@<output preamble of document@>=
+ KCHARP w_doc_index =
+ "\\input \"supp-pdf\"\n"
+ "\\input \"/usr/local/yacco2/diagrams/o2mac.tex\"\n"
+ "\\IDXlinkerdoctitle{%s}{%s}{%s}";
+ char xlate_file[Max_cweb_item_size];xlate_file[0] = (char)0;
+ char xlate_fscfile[Max_cweb_item_size];xlate_fscfile[0] = (char)0;
+ XLATE_SYMBOLS_FOR_cweave(w_linker_filename_.c_str(),xlate_file);
+ XLATE_SYMBOLS_FOR_cweave(cntl_file_name.c_str(),xlate_fscfile);
+ int x = sprintf(big_buf_
+ ,w_doc_index
+ ,xlate_file
+ ,xlate_file
+ ,xlate_fscfile
+ );
+ ow_linker_file_.write(big_buf_,x);
+ ow_linker_file_ << std::endl;
+ KCHARP w_doc_comments =
+ "@@** O2linker Index of Grammars.\\fbreak\n"
+ "The grammars are sorted lexicographically into 2 parts:\n"
+ "threads followed by the stand alone grammars.\n"
+ "Each grammar's called threads graph is determined from their \n"
+ " ``list-of-transitive-threads''\n"
+ "derived from this construct.%s";
+ x = sprintf(big_buf_,w_doc_comments," ");
+ ow_linker_file_.write(big_buf_,x);
+ ow_linker_file_ << std::endl;
+
+@*3 Loop thru grammars to gen their local linker doc info.
+@<loop thru grammars to gen their local linker doc info@>=
+ KCHARP w_grammar =
+ "@@*2 %s";
+ KCHARP w_comments =
+ "\\Linkeridxentryk{%s}";
+ KCHARP w_called_threads =
+ "\\Linkercalledthreadstitle%s";
+ char xlate_gfile[Max_cweb_item_size];
+ char rebuild_comment[Max_cweb_item_size];
+ char fandk[Max_cweb_item_size];
+ char xlate_thnm[Max_cweb_item_size];
+ char xlate_tnm[Max_cweb_item_size];
+
+ std::vector<table_entry*>::iterator ithi = GRAMMAR_DICTIONARY.begin();@/
+ std::vector<table_entry*>::iterator ithie = GRAMMAR_DICTIONARY.end();@/
+ for(;ithi != ithie;++ithi){// individually process each thread
+ xlate_gfile[0] = (char)0;
+ rebuild_comment[0] = (char)0;
+ fandk[0] = (char)0;
+ xlate_thnm[0] = (char)0;
+ xlate_tnm[0] = (char)0;
+
+ table_entry* tbl_entry = *ithi;
+ @=thread_attributes*th_att= ((th_in_stbl*)tbl_entry->symbol_)->thread_in_stbl();@>@/
+ @<make grammar's contents cweaveable and output@>;
+ @<output grammar's called threads list@>;
+ @<output grammar's first set@>;
+ @<output grammar's used threads@>;
+ }
+
+@*3 Output First set of linker.
+@<output First set of linker@>=
+ KCHARP w_fsc_file_listing =
+ "@@** First set control file (fsc) listing.\\fbreak\n"
+ "File : ``%s''\\fbreak\n"
+ "\\let\\setuplistinghook = \\relax\n"
+ "\\listing{\"%s\"}\n";
+ char xlated_filename[Max_cweb_item_size];
+
+XLATE_SYMBOLS_FOR_cweave(cntl_file_name.c_str(),xlated_filename);
+ x = sprintf(big_buf_
+ ,w_fsc_file_listing
+ ,xlated_filename
+ ,cntl_file_name.c_str()
+ );
+ ow_linker_file_.write(big_buf_,x);
+ ow_linker_file_ << std::endl;
+
+@*3 Output Index of linker.
+@<output Index of linker@>=
+ KCHARP w_index =
+ "@@** Index.%s";
+ x = sprintf(big_buf_,w_index," ");
+ ow_linker_file_.write(big_buf_,x);
+ ow_linker_file_ << std::endl;
+
+
+@*2 Output driver of the linker document.
+@<generate linker document@>=
+ gen_each_grammar_s_referenced_threads();
+ char big_buf_[BIG_BUFFER_32K];
+ std::string w_linker_filename_("o2linker_doc.w");
+ std::ofstream ow_linker_file_;
+ ow_linker_file_.open(w_linker_filename_.c_str(),ios_base::out|ios::trunc);
+ @<output preamble of document@>;
+ @<loop thru grammars to gen their local linker doc info@>;
+ @<output First set of linker@>;
+ @<output Index of linker@>;
+ ow_linker_file_.close();
+
+@** Emit code.\fbreak
+There is not too much to emit.\fbreak
+\ptindent{1) cpp preamble code --- time of day, and the grammar writer's preamble}
+\ptindent{2) threads include files and their namespace statement}
+\ptindent{3) global bit maps}
+\ptindent{4) global thread stable}
+\ptindent{5) global terminals and their thread bit maps}
+
+As an afterthought, the situation of having no threads to emit has been added.
+@<emit code@>=
+ cout << "Emit file name: " << linker_cntl_file_fsm.emitfile_filename_.c_str() << endl;
+ ofstream ofile(linker_cntl_file_fsm.emitfile_filename_.c_str(),ios::out);
+ if (!ofile){
+ cout << "Error - can't open emit file: "
+ << linker_cntl_file_fsm.emitfile_filename_.c_str() << endl;
+ return 1;
+ }
+ emit_cpp_preamble(ofile
+ ,linker_cntl_file_fsm.emitfile_filename_.c_str()
+ ,linker_cntl_file_fsm.preamble_srce_->syntax_code()->c_str());
+ emit_global_thread_include_files(ofile);
+ emit_global_bit_maps(ofile);
+ if(NO_OF_THREADS == 0){
+ emit_no_threads(ofile);
+ }else{
+ emit_global_thread_stable(ofile);
+ emit_T_fs_of_potential_threads(ofile);
+ }
+ ofile.close();
+
+@*2 Emit no threads.\fbreak
+A situation where the grammar writer has only standalone grammars; there
+are no parallel statements used within the grammars:
+${\vert\vert\vert}$ "returned token" called "thread".
+@<accrue linker code@>+=
+void emit_no_threads(ofstream& ofile){
+ ofile << "// There are NO THREADS emitted" << endl;
+ ofile << "void* yacco2::THDS_STABLE__ = 0;" << endl;
+ ofile << "void* yacco2::T_ARRAY_HAVING_THD_IDS__ = 0;" << endl;
+}
+
+@*2 Emit cpp preamble.
+@<accrue linker code@>+=
+void emit_cpp_preamble(ofstream& ofile,const char* OFile,const char* Preamble){
+ ofile << "//" << endl;
+ ofile << "// File: " << OFile << endl;
+ ofile << "// Generated by linker.exe" << endl;
+ ofile << "// Date and Time: " << DATE_AND_TIME() << endl;
+ ofile << "//" << endl;
+ ofile << endl;
+ ofile << "// Preamble code" << endl;
+ ofile << Preamble << endl;
+}
+
+@*2 Emit thread include files.\fbreak
+Unfortunately, a lot of verbage to resolve the thread's
+procedure. OhHum.
+
+Note, standalone grammars are not emitted. Why process them anyway?
+They provide thread calls that are added to the terminal's thread bit map.
+ @<accrue linker code@>+=
+void emit_global_thread_include_files(ofstream& ofile){
+ ofile << "// thread include and namespace" << std::endl;
+ char a[SMALL_BUFFER_4K];
+ KCHARP thread_include_ns = "#include \"%s.h\"";
+
+ std::vector<table_entry*>::iterator thi = GRAMMAR_DICTIONARY.begin();@/
+ std::vector<table_entry*>::iterator thie = GRAMMAR_DICTIONARY.end();@/
+ for(;thi != thie;++thi){
+ @=th_in_stbl*th_tbl= (th_in_stbl*)(*thi)->symbol_;@> @/
+ thread_attributes* th_att = th_tbl->thread_in_stbl();
+ if(th_att->monolithic_ == 'y') break;
+ int x = sprintf
+ (a
+ ,thread_include_ns
+ ,th_att->grammar_file_name_->c_string()->c_str()
+ );
+ ofile.write(a,x);
+ ofile << std::endl;
+ }
+}
+
+@*2 Emit global bit maps.
+@<accrue linker code@>+=
+void emit_global_bit_maps(ofstream& ofile){
+ ofile << "// BIT MAPS" << std::endl;
+ ofile << "#define TOTAL_NO_BIT_WORDS 2*1024*50" << std::endl;
+ ofile << "int yacco2::TOTAL_NO_BIT_WORDS__(TOTAL_NO_BIT_WORDS);" << std::endl;
+ ofile << "yacco2::ULINT bit_maps[TOTAL_NO_BIT_WORDS];" << std::endl;
+ ofile << "void* yacco2::BIT_MAPS_FOR_SALE__ = (void*)&bit_maps;" << std::endl;
+ ofile << "int yacco2::BIT_MAP_IDX__(0);" << std::endl;
+}
+
+@*2 Emit global thread stable |THDS_STABLE__|.\fbreak
+Read the |GRAMMAR_DICTIONARY| and emit a sorted |Thread_entry| list where
+each thread (excluded are the standalone grammars)
+has a global naming convention of Ixxx where the xxx is the thread name.
+The |Thread_entry| provides its literate name,
+ the thread function to be spawned, and its enumerate value
+used as an index into the array of threads.
+
+|THDS_STABLE__| is a global referenced by Yacco2's runtime library.
+It is a structure indicating the number of threads within its array and
+the array of addresses to each just-gened thread's |Thread_entry|. HoHum --- is
+this better than fe-fi-foe-fum I smell the blood of an ...?
+@<accrue linker code@>+=
+void emit_global_thread_stable(ofstream& ofile){
+ ofile << "// THREAD STABLE" << std::endl;
+ char a[BIG_BUFFER_32K];
+ KCHARP thread_entry = "yacco2::Thread_entry I%s = {%s,%s,%i,%s::PROC_%s};";
+ string quoted_name;
+ @<gen thread list@>;
+ @<gen global thread array@>;
+}
+
+@*2 The threading stew.
+@<gen thread list@>=
+ std::vector<table_entry*>::iterator thi = GRAMMAR_DICTIONARY.begin();@/
+ std::vector<table_entry*>::iterator thie = GRAMMAR_DICTIONARY.end();@/
+ for(;thi != thie;++thi){
+ @=th_in_stbl*th_tbl= (th_in_stbl*)(*thi)->symbol_;@> @/
+ thread_attributes* th_att = th_tbl->thread_in_stbl();
+ if(th_att->monolithic_ == 'y') break;
+ quoted_name.clear();
+ const char* th_name = th_att->thread_name_->c_string()->c_str();
+ quoted_name += '"';
+ quoted_name += th_name;
+ quoted_name += '"';
+
+ int x = sprintf(a,thread_entry,th_name,quoted_name.c_str()
+ ,th_att->fully_qualified_th_name_.c_str(),th_att->th_enum_
+ ,th_att->name_space_name_->c_string()->c_str()
+ ,th_att->thread_name_->c_string()->c_str());
+ ofile.write(a,x);
+ ofile << std::endl;
+ }
+
+@*2 The table h\^ote.\fbreak
+The thoroughbreds waiting for the ``and they'rrrre off''.
+@<gen global thread array@>=
+ div_t c = div(NO_OF_THREADS,BITS_PER_WORD);
+ if(c.rem != 0) ++c.quot;
+ NO_WORDS_FOR_BIT_MAP = c.quot;
+
+ KCHARP thread_array =
+ "struct thd_array_type {\n"
+ " yacco2::USINT no_entries__;\n"
+ " yacco2::Thread_entry* first_entry__[%i];"
+ "};\n"
+ "thd_array_type thd_array = {\n"
+ " %i\n"
+ " ,\n"
+ " {\n";
+ int x = sprintf(a,thread_array,NO_OF_THREADS,NO_OF_THREADS);
+
+ ofile.write(a,x);
+ ofile << std::endl;
+ bool first_entry(true);
+ thi = GRAMMAR_DICTIONARY.begin();
+ thie = GRAMMAR_DICTIONARY.end();
+ KCHARP thread_entry_name = "&I%s";
+ for(;thi!=thie;++thi){
+ @=th_in_stbl*th_tbl= (th_in_stbl*)(*thi)->symbol_;@> @/
+ thread_attributes* th_att = th_tbl->thread_in_stbl();
+ if(th_att->monolithic_ == 'y') break;
+ if(first_entry == true){
+ first_entry = false;
+ ofile << " ";
+ }else{
+ ofile << " ,";
+ }
+ int x = sprintf(a,thread_entry_name,th_att->thread_name_->c_string()->c_str());
+ ofile.write(a,x);
+ ofile << std::endl;
+ }
+ ofile << " }\n};" << endl;
+ @<announce the stable to the world@>;
+
+@*2 Announce the stable to the world.
+@<announce the stable to the world@>=
+ ofile << "void* yacco2::THDS_STABLE__ = (void*)&thd_array;" << endl;
+
+@*2 Emit global Terminals' thread bit maps.\fbreak
+This is the inverse to first sets: these are the threads that can
+run from the specific terminal.
+
+This global optimization determines whether the finite state table
+has the potential to run a thread. How so?
+Firstly, the local grammar determines
+whether threading is taking place in its current state configuration.
+If so, the current token is
+checked to see whether there are threads to possibly run using
+the global thread bit map specific to itself.
+With these potental threads the local state
+configuration is measured for activity.
+Then and only then will the
+just-in-time dynamics of building the grammar's local thread map occur and the
+found threads launched.
+
+This optimization stops stuttering: how so?
+Only threads having the current token in their first set get launched.
+The jiggles now are only real potential prefixes to parse by each launched thread.
+Remember, common prefixes get resolved by arbitration within the
+launching grammar specific to the current finite state configuration.
+
+Why the output to another file? The flatulence of Microsoft's compiler: an
+INTERNAL COMPILER ERROR ``C1001'' message.
+Well I found the typo that causes this draconian behavior: ``endl::endl''
+instead of ``std::endl''. This congers up speculative thoughts on how
+Microsoft's compiler is written. Enough of my racket: Back to appending
+to the same file.
+
+@<accrue linker code@>+=
+void emit_T_fs_of_potential_threads(ofstream& ofile){
+ ofile << "// Terminal thread sets" << std::endl;
+ int no_of_T = T_DICTIONARY.size();
+ char a[SMALL_BUFFER_4K];
+ KCHARP T_list_to_thd_list_type =
+ "struct T_%i_type{\n"
+ " yacco2::ULINT first_entry__[%i];\n"
+ "};\n";@/
+ KCHARP T_list_to_thd_list_var = "T_%i_type T_%i = {// for T: %s";@/
+ KCHARP thd_id_in_list = "//%i: %s";@/
+
+ INT_SET_LIST_ITER_type i = T_THREAD_ID_LIST.begin();@>@/
+ INT_SET_LIST_ITER_type ie = T_THREAD_ID_LIST.end();@>@/
+ int terminal_id(-1);
+ for(;i!=ie;++i){
+ ++terminal_id;@/
+ INT_SET_type& th_list = *i;
+ if(th_list.empty() == true) continue;
+ int x = sprintf(a,T_list_to_thd_list_type,terminal_id,NO_WORDS_FOR_BIT_MAP);
+ ofile.write(a,x);
+ ofile << std::endl;
+ @<create terminal's thread bit map@>;
+ }
+ @<emit array of Terminals' thread bit maps@>;
+}
+
+
+@*2 Create terminal's thread bit map.\fbreak
+As the number of threads are unknown,
+I use |SPECULATIVE_NO_BIT_WORDS| to reserve the space to manufacture
+the thread maps.
+See my comments in |Passover on code|.
+@<create terminal's thread bit map@>=
+ int no_thds_ids = th_list.size();
+ table_entry* t_entry = T_DICTIONARY[terminal_id];
+ tth_in_stbl* t_in_stbl= (tth_in_stbl*)t_entry->symbol_;
+ T_attributes* t_att= t_in_stbl->t_in_stbl();
+ x = sprintf(a
+ ,T_list_to_thd_list_var
+ ,terminal_id
+ ,terminal_id
+ ,t_att->fully_qualified_T_name_.c_str()
+ );
+ ofile.write(a,x);
+ ofile << std::endl;@/
+ ULINT word_map[SPECULATIVE_NO_BIT_WORDS]= {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+
+ INT_SET_ITER_type j = th_list.begin();
+ INT_SET_ITER_type je = th_list.end();
+
+ @<calculate terminal's thread bit map@>;
+ @<emit terminal's thread bit map@>;
+
+@*2 Calculate terminal's thread bit map.
+And print out their contents as comments.
+@<calculate terminal's thread bit map@>=
+ for(;j!=je;++j){
+ int th_id = *j;
+ table_entry* tbl_entry = GRAMMAR_DICTIONARY[th_id];
+ @=th_in_stbl*th_tbl= (th_in_stbl*)tbl_entry->symbol_;@> @/
+ thread_attributes* th_att = th_tbl->thread_in_stbl();
+ div_t bb = div(th_id,BITS_PER_WORD);
+ ULINT bit_pos_value = 1 << bb.rem;
+ word_map[bb.quot] |= bit_pos_value;
+ int x = sprintf(a,thd_id_in_list,th_id,th_att->thread_name_->c_string()->c_str());
+ ofile.write(a,x);
+ ofile << std::endl;
+ }
+
+@*2 Emit terminal's thread bit map.
+@<emit terminal's thread bit map@>=
+ for(int dd=1;dd<=NO_WORDS_FOR_BIT_MAP;++dd){
+ if(dd == 1) ofile << " {";
+ else ofile << " ,";
+ ofile << word_map[dd-1]<< endl;
+ }
+ ofile << " }" << endl;
+ ofile << "};" << endl;
+
+ @*2 Emit Terminals' thread bit maps and global |T_ARRAY_HAVING_THD_IDS__|.\fbreak
+ Go tell it to the ? or is it Yacco2?
+ @<emit array of Terminals' thread bit maps@>=
+ KCHARP T_array_type =
+ "struct t_array_type {\n"
+ " yacco2::USINT no_entries__;\n"
+ " yacco2::thd_ids_having_T* first_entry__[%i];\n"
+ "};";
+ int x = sprintf(a,T_array_type,no_of_T);
+ ofile.write(a,x);
+ ofile << std::endl;
+
+ KCHARP T_array =
+ "t_array_type t_array = {\n"
+ " %i\n"
+ " ,{";
+ x = sprintf
+ (a
+ ,T_array
+ ,no_of_T
+ );
+ ofile.write(a,x);
+ ofile << std::endl;
+
+ i = T_THREAD_ID_LIST.begin();
+ ie = T_THREAD_ID_LIST.end();@>@/
+ @<print out each thread set@>;
+ ofile << " }\n};" << endl;
+ ofile << "void* yacco2::T_ARRAY_HAVING_THD_IDS__ = (void*)&t_array;" << endl;
+
+@*2 Print each entry.\fbreak
+More coughing. Oh well.
+@<print out each thread set@>=
+ bool first_item(true);// regulates if a comma should be emitted
+ for(int t_id = -1;i!=ie;++i){
+ ++t_id;
+ table_entry* t_entry = T_DICTIONARY[t_id];@/
+ tth_in_stbl* t_in_stbl= (tth_in_stbl*)t_entry->symbol_;
+ T_attributes* t_att= t_in_stbl->t_in_stbl();
+ INT_SET_type& th_list = *i;
+ if(th_list.empty() == true){// no thds with this T as first set
+ if(first_item == true) first_item = false;
+ else ofile << " ,";
+ KCHARP T_array_entries = "%s// %s";
+ int x = sprintf(a,T_array_entries,"0",t_att->fully_qualified_T_name_.c_str());
+ ofile.write(a,x);
+ ofile << std::endl;
+ continue;
+ }else{
+ if(first_item == true) first_item = false;
+ else ofile << " ,";
+ KCHARP T_list_to_thd_list_var = "(yacco2::thd_ids_having_T*)&T_%i // %s";
+
+ int x = sprintf(a,T_list_to_thd_list_var,t_id,t_att->fully_qualified_T_name_.c_str());
+ ofile.write(a,x);
+ ofile << std::endl;
+ }
+ }
+
+@** Main line of Linker.
+@<accrue linker code@>=
+YACCO2_define_trace_variables();
+yacco2::TOKEN_GAGGLE Error_queue;@/
+STBL_T_ITEMS_type STBL_T_ITEMS;
+std::vector<NS_yacco2_terminals::table_entry*> GRAMMAR_DICTIONARY;@/
+std::map<std::string, std::vector<std::string> > USED_THREADS_LIST;@/
+std::vector<NS_yacco2_terminals::table_entry*> T_DICTIONARY;@/
+INT_SET_LIST_type T_THREAD_ID_LIST;
+
+int NO_OF_THREADS(0);@/
+int NO_WORDS_FOR_BIT_MAP(0);
+char Visit_graph[RESERVE_FIXED_NO_THREADS];
+extern void XLATE_SYMBOLS_FOR_cweave(const char* Sym_to_xlate,char* Xlated_sym);
+extern void PRINT_CALLED_THREAD_LIST
+ (yacco2::AST* Node,std::ofstream* Ow_linker_file,int Recursion_level);
+string cntl_file_name;
+yacco2::CHAR PRT_SW('n');
+
+int main(int argc, char* argv[])
+{
+ cout << yacco2::O2linker_VERSION << std::endl;
+ using namespace yacco2;
+ using namespace std;
+ load_linkkws_into_tbl();
+ cout << "Get command line and parse it " << endl;
+ GET_CMD_LINE(argc,argv,Linker_holding_file,Error_queue);
+ @<if error queue not empty then deal with posted errors@>;
+ LINKER_PARSE_CMD_LINE(Linker_holding_file,cntl_file_name,Error_queue);
+ @<if error queue not empty then deal with posted errors@>;
+ lrclog << yacco2::O2linker_VERSION << std::endl;
+ @<parse linker control file@>;
+ @<parse T alphabet@>;
+ @<parse fsc files@>;
+ @<post verify that there are no threads ``used'' and not ``defined''@>;
+ @<sort thread dictionary@>;
+ @<dump sorted dictionary@>;
+ @<count and re-align threads enumerate values to sorted position@>;
+ @<check whether Linker has enough space to gen thread bit maps: no throw up@>;
+ @<generate threads final first sets@>;
+ @<emit code@>;
+ @<generate linker document@>;
+ //|yacco2::Parallel_threads_shutdown(linker_cntl_file);|
+return 0;
+}
diff --git a/web/yacco2/o2linker/sampleoutput.w b/web/yacco2/o2linker/sampleoutput.w
new file mode 100644
index 0000000000..e3d80227b9
--- /dev/null
+++ b/web/yacco2/o2linker/sampleoutput.w
@@ -0,0 +1,23 @@
+@q file: sampleoutput.w@>
+@q% Copyright Dave Bone 1998 - 2015@>
+@q% /*@>
+@q% This Source Code Form is subject to the terms of the Mozilla Public@>
+@q% License, v. 2.0. If a copy of the MPL was not distributed with this@>
+@q% file, You can obtain one at http://mozilla.org/MPL/2.0/.@>
+@q% */@>
+@** Sample output from Linker.\fbreak
+A sampling from Yacco2's grammars.
+Have a look in the source code below where the following
+external variables are defined at line references 41, 43, 44, 72, and 193:\fbreak
+\ptindent{|yacco2::TOTAL_NO_BIT_WORDS__| }
+\ptindent{|yacco2::BIT_MAPS_FOR_SALE__| }
+\ptindent{|yacco2::BIT_MAP_IDX__| }
+\ptindent{|yacco2::THDS_STABLE__| }
+\ptindent{|yacco2::T_ARRAY_HAVING_THD_IDS__| }
+
+Yacoo2's parse library references them and they get resolved by the language linker.
+\let\setuplistinghook = \linenumberedlisting
+\listing{"/usr/local/yacco2/diagrams/sampleoutput.txt"}
+
+@*2 Sample 2: No threads outputted just a stand alone grammar.
+\listing{"/usr/local/yacco2/diagrams/sampleoutput2.txt"}
diff --git a/web/yacco2/o2linker/testsuites.w b/web/yacco2/o2linker/testsuites.w
new file mode 100644
index 0000000000..47e4c75f38
--- /dev/null
+++ b/web/yacco2/o2linker/testsuites.w
@@ -0,0 +1,15 @@
+@q file: testsuites.w@>
+@q% Copyright Dave Bone 1998 - 2015@>
+@q% /*@>
+@q% This Source Code Form is subject to the terms of the Mozilla Public@>
+@q% License, v. 2.0. If a copy of the MPL was not distributed with this@>
+@q% file, You can obtain one at http://mozilla.org/MPL/2.0/.@>
+@q% */@>
+*@** Test suites: Check out those flabby grammar muscles.\fbreak
+Exercise, exercise, excerise, perhaps to ... Linker's languages.
+Microsoft's batch facility is used to do the sweating.
+The test suites are inputted via the command line option on Linker.
+
+The batch file |linker_testsuite.bat| contains the all the test suites.
+Here are the test results with some editorial liberties:\fbreak
+\listing{"/usr/local/yacco2/diagrams/testsuiteoutput.txt"}