]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/m2/pge-boot/Gpge.c
Update copyright years.
[thirdparty/gcc.git] / gcc / m2 / pge-boot / Gpge.c
CommitLineData
1eee94d3
GM
1/* do not edit automatically generated by mc from pge. */
2/* pge.mod master source file of the ebnf parser generator.
3
83ffe9cd 4Copyright (C) 2003-2023 Free Software Foundation, Inc.
1eee94d3
GM
5Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.
6
7This file is part of GNU Modula-2.
8
9GNU Modula-2 is free software; you can redistribute it and/or modify
10it under the terms of the GNU General Public License as published by
11the Free Software Foundation; either version 3, or (at your option)
12any later version.
13
14GNU Modula-2 is distributed in the hope that it will be useful, but
15WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17General Public License for more details.
18
19You should have received a copy of the GNU General Public License
20along with GNU Modula-2; see the file COPYING3. If not see
21<http://www.gnu.org/licenses/>. */
22
23# if !defined (PROC_D)
24# define PROC_D
25 typedef void (*PROC_t) (void);
26 typedef struct { PROC_t proc; } PROC;
27# endif
28
29# if !defined (TRUE)
30# define TRUE (1==1)
31# endif
32
33# if !defined (FALSE)
34# define FALSE (1==0)
35# endif
36
37#include <stddef.h>
38#include <string.h>
39#include <limits.h>
40# include "GStorage.h"
41# include "Gmcrts.h"
42#if defined(__cplusplus)
43# undef NULL
44# define NULL 0
45#endif
46# include "GPushBackInput.h"
47# include "Gbnflex.h"
48# include "GStrLib.h"
49# include "GStorage.h"
50# include "GNameKey.h"
51# include "GNumberIO.h"
52# include "GSymbolKey.h"
53# include "GLists.h"
54# include "GDynamicStrings.h"
55# include "GASCII.h"
56# include "GStrIO.h"
57# include "GStdIO.h"
58# include "GDebug.h"
59# include "GArgs.h"
60# include "GSYSTEM.h"
61# include "Glibc.h"
62# include "GOutput.h"
63# include "GM2RTS.h"
64
65# define MaxCodeHunkLength 8192
66# define MaxFileName 8192
67# define MaxString 8192
68# define DefaultRecovery TRUE
69# define MaxElementsInSet 32
70# define BaseRightLimit 75
71# define BaseRightMargin 50
72# define BaseNewLine 3
73typedef struct pge_termdesc_r pge_termdesc;
74
75typedef pge_termdesc *pge_TermDesc;
76
77typedef struct pge_DoProcedure_p pge_DoProcedure;
78
79typedef unsigned int pge_SetOfStop;
80
81typedef struct pge__T1_r pge__T1;
82
83typedef pge__T1 *pge_IdentDesc;
84
85typedef struct pge__T2_r pge__T2;
86
87typedef pge__T2 *pge_ProductionDesc;
88
89typedef struct pge__T3_r pge__T3;
90
91typedef pge__T3 *pge_StatementDesc;
92
93typedef struct pge__T4_r pge__T4;
94
95typedef pge__T4 *pge_ExpressionDesc;
96
97typedef struct pge__T5_r pge__T5;
98
99typedef struct pge__T6_r pge__T6;
100
101typedef pge__T6 *pge_FollowDesc;
102
103typedef struct pge__T7_r pge__T7;
104
105typedef pge__T7 *pge_SetDesc;
106
107typedef struct pge__T8_r pge__T8;
108
109typedef pge__T8 *pge_CodeDesc;
110
111typedef struct pge__T9_r pge__T9;
112
113typedef pge__T9 *pge_CodeHunk;
114
115typedef struct pge__T10_a pge__T10;
116
117typedef struct pge__T11_a pge__T11;
118
119typedef enum {pge_idel, pge_tokel, pge_litel} pge_ElementType;
120
121typedef enum {pge_m2none, pge_m2if, pge_m2elsif, pge_m2while} pge_m2condition;
122
123typedef enum {pge_unknown, pge_true, pge_false} pge_TraverseResult;
124
125typedef enum {pge_id, pge_lit, pge_sub, pge_opt, pge_mult, pge_m2} pge_FactorType;
126
127typedef pge__T5 *pge_FactorDesc;
128
129struct pge_termdesc_r {
130 pge_FactorDesc factor;
131 pge_TermDesc next;
132 pge_FollowDesc followinfo;
133 unsigned int line;
134 };
135
136typedef void (*pge_DoProcedure_t) (pge_ProductionDesc);
137struct pge_DoProcedure_p { pge_DoProcedure_t proc; };
138
139struct pge__T1_r {
140 pge_ProductionDesc definition;
141 NameKey_Name name;
142 unsigned int line;
143 };
144
145struct pge__T2_r {
146 pge_ProductionDesc next;
147 pge_StatementDesc statement;
148 pge_SetDesc first;
149 unsigned int firstsolved;
150 pge_FollowDesc followinfo;
151 unsigned int line;
152 NameKey_Name description;
153 };
154
155struct pge__T3_r {
156 pge_IdentDesc ident;
157 pge_ExpressionDesc expr;
158 pge_FollowDesc followinfo;
159 unsigned int line;
160 };
161
162struct pge__T4_r {
163 pge_TermDesc term;
164 pge_FollowDesc followinfo;
165 unsigned int line;
166 };
167
168struct pge__T5_r {
169 pge_FollowDesc followinfo;
170 pge_FactorDesc next;
171 unsigned int line;
172 pge_FactorDesc pushed;
173 pge_FactorType type; /* case tag */
174 union {
175 pge_IdentDesc ident;
176 NameKey_Name string;
177 pge_ExpressionDesc expr;
178 pge_CodeDesc code;
179 };
180 };
181
182struct pge__T6_r {
183 unsigned int calcfollow;
184 pge_SetDesc follow;
185 pge_TraverseResult reachend;
186 pge_TraverseResult epsilon;
187 unsigned int line;
188 };
189
190struct pge__T7_r {
191 pge_SetDesc next;
192 pge_ElementType type; /* case tag */
193 union {
194 pge_IdentDesc ident;
195 NameKey_Name string;
196 };
197 };
198
199struct pge__T8_r {
200 pge_CodeHunk code;
201 unsigned int indent;
202 unsigned int line;
203 };
204
205struct pge__T10_a { char array[MaxCodeHunkLength+1]; };
206struct pge__T11_a { char array[MaxFileName+1]; };
207struct pge__T9_r {
208 pge__T10 codetext;
209 pge_CodeHunk next;
210 };
211
212static unsigned int LastLineNo;
213static unsigned int Finished;
214static unsigned int SuppressFileLineTag;
215static unsigned int KeywordFormatting;
216static unsigned int PrettyPrint;
217static unsigned int EmitCode;
218static unsigned int Texinfo;
219static unsigned int Sphinx;
220static unsigned int FreeDocLicense;
221static unsigned int Debugging;
222static unsigned int WasNoError;
223static unsigned int LinePrologue;
224static unsigned int LineEpilogue;
225static unsigned int LineDeclaration;
226static pge_CodeHunk CodePrologue;
227static pge_CodeHunk CodeEpilogue;
228static pge_CodeHunk CodeDeclaration;
229static pge_ProductionDesc CurrentProduction;
230static pge_ProductionDesc TailProduction;
231static pge_ProductionDesc HeadProduction;
232static pge_ExpressionDesc CurrentExpression;
233static pge_TermDesc CurrentTerm;
234static pge_FactorDesc CurrentFactor;
235static pge_IdentDesc CurrentIdent;
236static pge_StatementDesc CurrentStatement;
237static pge_SetDesc CurrentSetDesc;
238static SymbolKey_SymbolTree ReverseValues;
239static SymbolKey_SymbolTree Values;
240static SymbolKey_SymbolTree ReverseAliases;
241static SymbolKey_SymbolTree Aliases;
242static NameKey_Name ModuleName;
243static NameKey_Name LastLiteral;
244static NameKey_Name LastIdent;
245static NameKey_Name SymIsProc;
246static NameKey_Name TokenTypeProc;
247static NameKey_Name ErrorProcArray;
248static NameKey_Name ErrorProcString;
249static pge__T11 ArgName;
250static pge__T11 FileName;
251static unsigned int OnLineStart;
252static unsigned int BeginningOfLine;
253static unsigned int Indent;
254static unsigned int EmittedVar;
255static unsigned int ErrorRecovery;
256static unsigned int LargestValue;
257static unsigned int InitialElement;
258static unsigned int ParametersUsed;
259
260/*
261 DescribeStop - issues a message explaining what tokens were expected
262*/
263
264static DynamicStrings_String DescribeStop (pge_SetOfStop stopset);
265
266/*
267 DescribeError - issues a message explaining what tokens were expected
268*/
269
270static void DescribeError (void);
271
272/*
273 AddEntry - adds an entry into, t, containing [def:value].
274*/
275
276static void AddEntry (SymbolKey_SymbolTree *t, NameKey_Name def, NameKey_Name value);
277
278/*
279 Format1 - converts string, src, into, dest, together with encapsulated
280 entity, n. It only formats the first %s or %d with n.
281*/
282
283static void Format1 (const char *src_, unsigned int _src_high, unsigned int n, char *dest, unsigned int _dest_high);
284
285/*
286 WarnError1 -
287*/
288
289static void WarnError1 (const char *a_, unsigned int _a_high, unsigned int n);
290
291/*
292 PrettyFollow -
293*/
294
295static void PrettyFollow (const char *start_, unsigned int _start_high, const char *end_, unsigned int _end_high, pge_FollowDesc f);
296
297/*
298 NewFollow - creates a new follow descriptor and returns the data structure.
299*/
300
301static pge_FollowDesc NewFollow (void);
302
303/*
304 AssignEpsilon - assigns the epsilon value and sets the epsilon to value,
305 providing condition is TRUE.
306*/
307
308static void AssignEpsilon (unsigned int condition, pge_FollowDesc f, pge_TraverseResult value);
309
310/*
311 GetEpsilon - returns the value of epsilon
312*/
313
314static pge_TraverseResult GetEpsilon (pge_FollowDesc f);
315
316/*
317 AssignReachEnd - assigns the reachend value providing that, condition, is TRUE.
318*/
319
320static void AssignReachEnd (unsigned int condition, pge_FollowDesc f, pge_TraverseResult value);
321
322/*
323 GetReachEnd - returns the value of reachend
324*/
325
326static pge_TraverseResult GetReachEnd (pge_FollowDesc f);
327
328/*
329 AssignFollow - assigns the follow set and sets the calcfollow to TRUE.
330*/
331
332static void AssignFollow (pge_FollowDesc f, pge_SetDesc s);
333
334/*
335 GetFollow - returns the follow set.
336*/
337
338static pge_SetDesc GetFollow (pge_FollowDesc f);
339
340/*
341 NewProduction - creates a new production and returns the data structure.
342*/
343
344static pge_ProductionDesc NewProduction (void);
345
346/*
347 NewFactor -
348*/
349
350static pge_FactorDesc NewFactor (void);
351
352/*
353 NewTerm - returns a new term.
354*/
355
356static pge_TermDesc NewTerm (void);
357
358/*
359 NewExpression - returns a new expression.
360*/
361
362static pge_ExpressionDesc NewExpression (void);
363
364/*
365 NewStatement - returns a new statement.
366*/
367
368static pge_StatementDesc NewStatement (void);
369
370/*
371 NewSetDesc - creates a new set description and returns the data structure.
372*/
373
374static pge_SetDesc NewSetDesc (void);
375
376/*
377 NewCodeDesc - creates a new code descriptor and initializes all fields to zero.
378*/
379
380static pge_CodeDesc NewCodeDesc (void);
381
382/*
383 CodeFragmentPrologue - consumes code text up to a "%" after a newline.
384*/
385
386static void CodeFragmentPrologue (void);
387
388/*
389 CodeFragmentEpilogue - consumes code text up to a "%" after a newline.
390*/
391
392static void CodeFragmentEpilogue (void);
393
394/*
395 CodeFragmentDeclaration - consumes code text up to a "%" after a newline.
396*/
397
398static void CodeFragmentDeclaration (void);
399
400/*
401 GetCodeFragment - collects the code fragment up until ^ %
402*/
403
404static void GetCodeFragment (pge_CodeHunk *h);
405
406/*
407 WriteCodeHunkList - writes the CodeHunk list in the correct order.
408*/
409
410static void WriteCodeHunkList (pge_CodeHunk l);
411
412/*
413 WriteIndent - writes, n, spaces.
414*/
415
416static void WriteIndent (unsigned int n);
417
418/*
419 CheckWrite -
420*/
421
422static void CheckWrite (char ch, unsigned int *curpos, unsigned int left, unsigned int *seentext);
423
424/*
425 WriteStringIndent - writes a string but it will try and remove upto indent spaces
426 if they exist.
427*/
428
429static void WriteStringIndent (const char *a_, unsigned int _a_high, unsigned int indent, unsigned int *curpos, unsigned int left, unsigned int *seentext);
430
431/*
432 WriteCodeHunkListIndent - writes the CodeHunk list in the correct order
433 but it removes up to indent spaces if they exist.
434*/
435
436static void WriteCodeHunkListIndent (pge_CodeHunk l, unsigned int indent, unsigned int *curpos, unsigned int left, unsigned int *seentext);
437
438/*
439 Add - adds a character to a code hunk and creates another code hunk if necessary.
440*/
441
442static pge_CodeHunk Add (pge_CodeHunk *p, char ch, unsigned int *i);
443
444/*
445 ConsHunk - combine two possible code hunks.
446*/
447
448static void ConsHunk (pge_CodeHunk *p, pge_CodeHunk q);
449
450/*
451 GetName - returns the next symbol which is checked for a legal name.
452*/
453
454static NameKey_Name GetName (void);
455
456/*
457 SyntaxError - after a syntax error we skip all tokens up until we reach
458 a stop symbol.
459*/
460
461static void SyntaxError (pge_SetOfStop stop);
462
463/*
464 SyntaxCheck -
465*/
466
467static void SyntaxCheck (pge_SetOfStop stop);
468
469/*
470 Expect -
471*/
472
473static void Expect (bnflex_TokenType t, pge_SetOfStop stop);
474
475/*
476 Ident - error checking varient of Ident
477*/
478
479static void Ident (pge_SetOfStop stop);
480
481/*
482 Modula2Code - error checking varient of Modula2Code
483*/
484
485static void Modula2Code (pge_SetOfStop stop);
486
487/*
488 StartModName := % ModuleName := GetName() ; ignore begintok CodeFragmentPrologue % =:
489*/
490
491static void StartModName (pge_SetOfStop stop);
492
493/*
494 EndModName :=
495*/
496
497static void EndModName (pge_SetOfStop stop);
498
499/*
500 DoDeclaration := % CodeFragmentDeclaration % =:
501*/
502
503static void DoDeclaration (pge_SetOfStop stop);
504
505/*
506 CollectLiteral :=
507 % LastLiteral := GetCurrentToken() ;
508 AdvanceToken ; %
509
510
511 first symbols:literaltok
512
513 cannot reachend
514*/
515
516static void CollectLiteral (pge_SetOfStop stopset);
517
518/*
519 CollectTok :=
520 % CurrentSetDesc := NewSetDesc() ;
521 WITH CurrentSetDesc^ DO
522 type := tokel ;
523 string := GetCurrentToken() ;
524 END ;
525 IF NOT ContainsSymKey(Values, GetCurrentToken())
526 THEN
527 AddEntry(Values, GetCurrentToken(), LargestValue) ;
528 AddEntry(ReverseValues, Name(LargestValue), GetCurrentToken()) ;
529 AddEntry(Aliases, GetCurrentToken(), GetCurrentToken()) ;
530 AddEntry(ReverseAliases, GetCurrentToken(), GetCurrentToken()) ;
531 INC(LargestValue)
532 END ;
533 AdvanceToken() ; %
534
535
536 first symbols:identtok
537
538 cannot reachend
539*/
540
541static void CollectTok (pge_SetOfStop stopset);
542
543/*
544 DefineToken :=
545 % AddEntry(Aliases, LastLiteral, GetCurrentToken()) ;
546 AddEntry(ReverseAliases, GetCurrentToken(), LastLiteral) ;
547 AddEntry(Values, GetCurrentToken(), LargestValue) ;
548 AddEntry(ReverseValues, Name(LargestValue), GetCurrentToken()) ;
549 INC(LargestValue) ;
550 AdvanceToken ; %
551
552
553 first symbols:identtok
554
555 cannot reachend
556*/
557
558static void DefineToken (pge_SetOfStop stopset);
559
560/*
561 Rules := '%' 'rules' { Defs } ExtBNF
562
563 first symbols:codetok
564
565 cannot reachend
566*/
567
568static void Rules (pge_SetOfStop stopset);
569
570/*
571 Special := Ident
572 % VAR p: ProductionDesc ; %
573
574 % p := NewProduction() ;
575 p^.statement := NewStatement() ;
576 p^.statement^.followinfo^.calcfollow := TRUE ;
577 p^.statement^.followinfo^.epsilon := false ;
578 p^.statement^.followinfo^.reachend := false ;
579 p^.statement^.ident := CurrentIdent ;
580 p^.statement^.expr := NIL ;
581 p^.firstsolved := TRUE ;
582 p^.followinfo^.calcfollow := TRUE ;
583 p^.followinfo^.epsilon := false ;
584 p^.followinfo^.reachend := false %
585 First Follow [ 'epsilon'
586 % p^.statement^.followinfo^.epsilon := true ; these are not used - but they are displayed when debugging
587 p^.statement^.followinfo^.reachend := true ;
588 p^.followinfo^.epsilon := true ;
589 p^.followinfo^.reachend := true
590 %
591 ] [ Literal
592 % p^.description := LastLiteral %
593 ]
594
595 first symbols:identtok
596
597 cannot reachend
598*/
599
600static void Special (pge_SetOfStop stopset);
601
602/*
603 Factor := '%' Modula2Code '%' |
604 Ident
605 % WITH CurrentFactor^ DO
606 type := id ;
607 ident := CurrentIdent
608 END ; %
609 | Literal
610 % WITH CurrentFactor^ DO
611 type := lit ;
612 string := LastLiteral ;
613 IF GetSymKey(Aliases, LastLiteral)=NulName
614 THEN
615 WarnError1('no token defined for literal %s', LastLiteral)
616 END
617 END ; %
618 | '{'
619 % WITH CurrentFactor^ DO
620 type := mult ;
621 expr := NewExpression() ;
622 CurrentExpression := expr ;
623 END ; %
624 Expression '}' | '['
625 % WITH CurrentFactor^ DO
626 type := opt ;
627 expr := NewExpression() ;
628 CurrentExpression := expr ;
629 END ; %
630 Expression ']' | '('
631 % WITH CurrentFactor^ DO
632 type := sub ;
633 expr := NewExpression() ;
634 CurrentExpression := expr ;
635 END ; %
636 Expression ')'
637
638 first symbols:dquotetok, squotetok, lparatok, lsparatok, lcparatok, identtok, codetok
639
640 cannot reachend
641*/
642
643static void Factor (pge_SetOfStop stopset);
644
645/*
646 Statement :=
647 % VAR i: IdentDesc ; %
648 Ident
649 % VAR p: ProductionDesc ; %
650
651 % p := FindDefinition(CurrentIdent^.name) ;
652 IF p=NIL
653 THEN
654 p := NewProduction()
655 ELSE
656 IF NOT ((p^.statement=NIL) OR (p^.statement^.expr=NIL))
657 THEN
658 WarnError1('already declared rule %s', CurrentIdent^.name)
659 END
660 END ;
661 i := CurrentIdent ; %
662 ':='
663 % VAR e: ExpressionDesc ; %
664
665 % e := NewExpression() ;
666 CurrentExpression := e ; %
667
668 % VAR s: StatementDesc ; %
669
670 % s := NewStatement() ;
671 WITH s^ DO
672 ident := i ;
673 expr := e
674 END ; %
675 Expression
676 % p^.statement := s ; %
677 '=:'
678
679 first symbols:identtok
680
681 cannot reachend
682*/
683
684static void Statement (pge_SetOfStop stopset);
685
686/*
687 Defs := 'special' Special | 'token' Token |
688 'error' ErrorProcedures |
689 'tokenfunc' TokenProcedure |
690 'symfunc' SymProcedure
691
692 first symbols:symfunctok, tfunctok, errortok, tokentok, specialtok
693
694 cannot reachend
695*/
696
697static void Defs (pge_SetOfStop stopset);
698
699/*
700 ExtBNF := 'BNF' { Production } 'FNB'
701
702 first symbols:BNFtok
703
704 cannot reachend
705*/
706
707static void ExtBNF (pge_SetOfStop stopset);
708
709/*
710 Main := Header Decls Footer Rules
711
712 first symbols:codetok
713
714 cannot reachend
715*/
716
717static void Main (pge_SetOfStop stopset);
718
719/*
720 Header := '%' 'module' StartModName
721
722 first symbols:codetok
723
724 cannot reachend
725*/
726
727static void Header (pge_SetOfStop stopset);
728
729/*
730 Decls := '%' 'declaration' DoDeclaration
731
732 first symbols:codetok
733
734 cannot reachend
735*/
736
737static void Decls (pge_SetOfStop stopset);
738
739/*
740 Footer := '%' 'module' EndModName
741
742 first symbols:codetok
743
744 cannot reachend
745*/
746
747static void Footer (pge_SetOfStop stopset);
748
749/*
750 First := 'first' '{' { LitOrTokenOrIdent
751 % WITH CurrentSetDesc^ DO
752 next := TailProduction^.first ;
753 END ;
754 TailProduction^.first := CurrentSetDesc
755 %
756 } '}'
757
758 first symbols:firsttok
759
760 cannot reachend
761*/
762
763static void First (pge_SetOfStop stopset);
764
765/*
766 Follow := 'follow' '{' { LitOrTokenOrIdent
767 % WITH CurrentSetDesc^ DO
768 next := TailProduction^.followinfo^.follow ;
769 END ;
770 TailProduction^.followinfo^.follow := CurrentSetDesc
771 %
772 } '}'
773
774 first symbols:followtok
775
776 cannot reachend
777*/
778
779static void Follow (pge_SetOfStop stopset);
780
781/*
782 LitOrTokenOrIdent := Literal
783 % CurrentSetDesc := NewSetDesc() ;
784 WITH CurrentSetDesc^ DO
785 type := litel ;
786 string := LastLiteral ;
787 END ;
788 %
789 | '<' CollectTok '>' |
790 Ident
791 % CurrentSetDesc := NewSetDesc() ;
792 WITH CurrentSetDesc^ DO
793 type := idel ;
794 ident := CurrentIdent ;
795 END ;
796 %
797
798
799 first symbols:dquotetok, squotetok, identtok, lesstok
800
801 cannot reachend
802*/
803
804static void LitOrTokenOrIdent (pge_SetOfStop stopset);
805
806/*
807 Literal := '"' CollectLiteral '"' |
808 "'" CollectLiteral "'"
809
810 first symbols:squotetok, dquotetok
811
812 cannot reachend
813*/
814
815static void Literal (pge_SetOfStop stopset);
816
817/*
818 Token := Literal DefineToken
819
820 first symbols:dquotetok, squotetok
821
822 cannot reachend
823*/
824
825static void Token (pge_SetOfStop stopset);
826
827/*
828 ErrorProcedures := Literal
829 % ErrorProcArray := LastLiteral %
830 Literal
831 % ErrorProcString := LastLiteral %
832
833
834 first symbols:dquotetok, squotetok
835
836 cannot reachend
837*/
838
839static void ErrorProcedures (pge_SetOfStop stopset);
840
841/*
842 TokenProcedure := Literal
843 % TokenTypeProc := LastLiteral %
844
845
846 first symbols:dquotetok, squotetok
847
848 cannot reachend
849*/
850
851static void TokenProcedure (pge_SetOfStop stopset);
852
853/*
854 SymProcedure := Literal
855 % SymIsProc := LastLiteral %
856
857
858 first symbols:dquotetok, squotetok
859
860 cannot reachend
861*/
862
863static void SymProcedure (pge_SetOfStop stopset);
864
865/*
866 Production := Statement
867
868 first symbols:identtok
869
870 cannot reachend
871*/
872
873static void Production (pge_SetOfStop stopset);
874
875/*
876 Expression :=
877 % VAR t1, t2: TermDesc ;
878 e : ExpressionDesc ; %
879
880 % e := CurrentExpression ;
881 t1 := NewTerm() ;
882 CurrentTerm := t1 ; %
883 Term
884 % e^.term := t1 ; %
885 { '|'
886 % t2 := NewTerm() ;
887 CurrentTerm := t2 %
888 Term
889 % t1^.next := t2 ;
890 t1 := t2 %
891 }
892
893 first symbols:dquotetok, squotetok, lparatok, lsparatok, lcparatok, identtok, codetok
894
895 cannot reachend
896*/
897
898static void Expression (pge_SetOfStop stopset);
899
900/*
901 Term :=
902 % VAR t1: TermDesc ; f1, f2: FactorDesc ; %
903
904 % CurrentFactor := NewFactor() ;
905 f1 := CurrentFactor ;
906 t1 := CurrentTerm ; %
907 Factor
908 % t1^.factor := f1 ;
909 f2 := NewFactor() ;
910 CurrentFactor := f2 %
911 { Factor
912 % f1^.next := f2 ;
913 f1 := f2 ;
914 f2 := NewFactor() ;
915 CurrentFactor := f2 ; %
916 }
917
918 first symbols:squotetok, dquotetok, codetok, identtok, lcparatok, lsparatok, lparatok
919
920 cannot reachend
921*/
922
923static void Term (pge_SetOfStop stopset);
924
925/*
926 GetDefinitionName - returns the name of the rule inside, p.
927*/
928
929static NameKey_Name GetDefinitionName (pge_ProductionDesc p);
930
931/*
932 FindDefinition - searches and returns the rule which defines, n.
933*/
934
935static pge_ProductionDesc FindDefinition (NameKey_Name n);
936
937/*
938 BackPatchIdent - found an ident, i, we must look for the corresponding rule and
939 set the definition accordingly.
940*/
941
942static void BackPatchIdent (pge_IdentDesc i);
943
944/*
945 BackPatchFactor - runs through the factor looking for an ident
946*/
947
948static void BackPatchFactor (pge_FactorDesc f);
949
950/*
951 BackPatchTerm - runs through all terms to find idents.
952*/
953
954static void BackPatchTerm (pge_TermDesc t);
955
956/*
957 BackPatchExpression - runs through the term to find any idents.
958*/
959
960static void BackPatchExpression (pge_ExpressionDesc e);
961
962/*
963 BackPatchSet -
964*/
965
966static void BackPatchSet (pge_SetDesc s);
967
968/*
969 BackPatchIdentToDefinitions - search through all the rules and add a link from any ident
970 to the definition.
971*/
972
973static void BackPatchIdentToDefinitions (pge_ProductionDesc d);
974
975/*
976 CalculateFirstAndFollow -
977*/
978
979static void CalculateFirstAndFollow (pge_ProductionDesc p);
980
981/*
982 ForeachRuleDo -
983*/
984
985static void ForeachRuleDo (pge_DoProcedure p);
986
987/*
988 WhileNotCompleteDo -
989*/
990
991static void WhileNotCompleteDo (pge_DoProcedure p);
992
993/*
994 NewLine - generate a newline and indent.
995*/
996
997static void NewLine (unsigned int Left);
998
999/*
1000 CheckNewLine -
1001*/
1002
1003static void CheckNewLine (unsigned int Left);
1004
1005/*
1006 IndentString - writes out a string with a preceeding indent.
1007*/
1008
1009static void IndentString (const char *a_, unsigned int _a_high);
1010
1011/*
1012 KeyWord - writes out a keywork with optional formatting directives.
1013*/
1014
1015static void KeyWord (NameKey_Name n);
1016
1017/*
1018 PrettyPara -
1019*/
1020
1021static void PrettyPara (const char *c1_, unsigned int _c1_high, const char *c2_, unsigned int _c2_high, pge_ExpressionDesc e, unsigned int Left);
1022
1023/*
1024 WriteKeyTexinfo -
1025*/
1026
1027static void WriteKeyTexinfo (NameKey_Name s);
1028
1029/*
1030 PrettyCommentFactor -
1031*/
1032
1033static void PrettyCommentFactor (pge_FactorDesc f, unsigned int Left);
1034
1035/*
1036 PeepTerm - returns the length of characters in term.
1037*/
1038
1039static unsigned int PeepTerm (pge_TermDesc t);
1040
1041/*
1042 PeepExpression - returns the length of the expression.
1043*/
1044
1045static unsigned int PeepExpression (pge_ExpressionDesc e);
1046
1047/*
1048 PeepFactor - returns the length of character in the factor
1049*/
1050
1051static unsigned int PeepFactor (pge_FactorDesc f);
1052
1053/*
1054 PrettyCommentTerm -
1055*/
1056
1057static void PrettyCommentTerm (pge_TermDesc t, unsigned int Left);
1058
1059/*
1060 PrettyCommentExpression -
1061*/
1062
1063static void PrettyCommentExpression (pge_ExpressionDesc e, unsigned int Left);
1064
1065/*
1066 PrettyCommentStatement -
1067*/
1068
1069static void PrettyCommentStatement (pge_StatementDesc s, unsigned int Left);
1070
1071/*
1072 PrettyCommentProduction - generates the comment for rule, p.
1073*/
1074
1075static void PrettyCommentProduction (pge_ProductionDesc p);
1076
1077/*
1078 PrettyPrintProduction - pretty prints the ebnf rule, p.
1079*/
1080
1081static void PrettyPrintProduction (pge_ProductionDesc p);
1082
1083/*
1084 EmitFileLineTag - emits a line and file tag using the C preprocessor syntax.
1085*/
1086
1087static void EmitFileLineTag (unsigned int line);
1088
1089/*
1090 EmitRule - generates a comment and code for rule, p.
1091*/
1092
1093static void EmitRule (pge_ProductionDesc p);
1094
1095/*
1096 CodeCondition -
1097*/
1098
1099static void CodeCondition (pge_m2condition m);
1100
1101/*
1102 CodeThenDo - codes a "THEN" or "DO" depending upon, m.
1103*/
1104
1105static void CodeThenDo (pge_m2condition m);
1106
1107/*
1108 CodeElseEnd - builds an ELSE END statement using string, end.
1109*/
1110
1111static void CodeElseEnd (const char *end_, unsigned int _end_high, unsigned int consumed, pge_FactorDesc f, unsigned int inopt);
1112
1113/*
1114 CodeEnd - codes a "END" depending upon, m.
1115*/
1116
1117static void CodeEnd (pge_m2condition m, pge_TermDesc t, unsigned int consumed, pge_FactorDesc f, unsigned int inopt);
1118
1119/*
1120 EmitNonVarCode - writes out, code, providing it is not a variable declaration.
1121*/
1122
1123static void EmitNonVarCode (pge_CodeDesc code, unsigned int curpos, unsigned int left);
1124
1125/*
1126 ChainOn -
1127*/
1128
1129static pge_FactorDesc ChainOn (pge_FactorDesc codeStack, pge_FactorDesc f);
1130
1131/*
1132 FlushCode -
1133*/
1134
1135static void FlushCode (pge_FactorDesc *codeStack);
1136
1137/*
1138 CodeFactor -
1139*/
1140
1141static void CodeFactor (pge_FactorDesc f, pge_TermDesc t, pge_m2condition l, pge_m2condition n, unsigned int inopt, unsigned int inwhile, unsigned int consumed, pge_FactorDesc codeStack);
1142
1143/*
1144 CodeTerm -
1145*/
1146
1147static void CodeTerm (pge_TermDesc t, pge_m2condition m, unsigned int inopt, unsigned int inwhile, unsigned int consumed, pge_FactorDesc codeStack);
1148
1149/*
1150 CodeExpression -
1151*/
1152
1153static void CodeExpression (pge_ExpressionDesc e, pge_m2condition m, unsigned int inopt, unsigned int inwhile, unsigned int consumed, pge_FactorDesc codeStack);
1154
1155/*
1156 CodeStatement -
1157*/
1158
1159static void CodeStatement (pge_StatementDesc s, pge_m2condition m);
1160
1161/*
1162 CodeProduction - only encode grammer rules which are not special.
1163*/
1164
1165static void CodeProduction (pge_ProductionDesc p);
1166
1167/*
1168 RecoverCondition -
1169*/
1170
1171static void RecoverCondition (pge_m2condition m);
1172
1173/*
1174 ConditionIndent - returns the number of spaces indentation created via, m.
1175*/
1176
1177static unsigned int ConditionIndent (pge_m2condition m);
1178
1179/*
1180 WriteGetTokenType - writes out the method of determining the token type.
1181*/
1182
1183static void WriteGetTokenType (void);
1184
1185/*
1186 NumberOfElements - returns the number of elements in set, to, which lie between low..high
1187*/
1188
1189static unsigned int NumberOfElements (pge_SetDesc to, unsigned int low, unsigned int high);
1190
1191/*
1192 WriteElement - writes the literal name for element, e.
1193*/
1194
1195static void WriteElement (unsigned int e);
1196
1197/*
1198 EmitIsInSet - writes out the equivalent of GetTokenType() IN { toset }
1199*/
1200
1201static void EmitIsInSet (pge_SetDesc to, NameKey_Name low, NameKey_Name high);
1202
1203/*
1204 EmitIsInSubSet - writes out a test to see whether GetTokenype() is in { subset }
1205*/
1206
1207static void EmitIsInSubSet (pge_SetDesc to, unsigned int low, unsigned int high);
1208
1209/*
1210 EmitIsInFirst -
1211*/
1212
1213static void EmitIsInFirst (pge_SetDesc to, pge_m2condition m);
1214static void FlushRecoverCode (pge_FactorDesc *codeStack);
1215
1216/*
1217 RecoverFactor -
1218*/
1219
1220static void RecoverFactor (pge_FactorDesc f, pge_m2condition m, pge_FactorDesc codeStack);
1221
1222/*
1223 OptExpSeen - returns TRUE if we can see an optional expression in the factor.
1224 This is not the same as epsilon. Example { '+' } matches epsilon as
1225 well as { '+' | '-' } but OptExpSeen returns TRUE in the second case
1226 and FALSE in the first.
1227*/
1228
1229static unsigned int OptExpSeen (pge_FactorDesc f);
1230
1231/*
1232 RecoverTerm -
1233*/
1234
1235static void RecoverTerm (pge_TermDesc t, pge_m2condition new_, pge_m2condition old);
1236
1237/*
1238 RecoverExpression -
1239*/
1240
1241static void RecoverExpression (pge_ExpressionDesc e, pge_m2condition new_, pge_m2condition old);
1242
1243/*
1244 RecoverStatement -
1245*/
1246
1247static void RecoverStatement (pge_StatementDesc s, pge_m2condition m);
1248
1249/*
1250 EmitFirstFactor - generate a list of all first tokens between the range: low..high.
1251*/
1252
1253static void EmitFirstFactor (pge_FactorDesc f, unsigned int low, unsigned int high);
1254
1255/*
1256 EmitUsed -
1257*/
1258
1259static void EmitUsed (unsigned int wordno);
1260
1261/*
1262 EmitStopParameters - generate the stop set.
1263*/
1264
1265static void EmitStopParameters (unsigned int FormalParameters);
1266
1267/*
1268 IsBetween - returns TRUE if the value of the token, string, is
1269 in the range: low..high
1270*/
1271
1272static unsigned int IsBetween (NameKey_Name string, unsigned int low, unsigned int high);
1273
1274/*
1275 IsEmptySet - returns TRUE if no elements exist in set, to, with values, low..high.
1276*/
1277
1278static unsigned int IsEmptySet (pge_SetDesc to, unsigned int low, unsigned int high);
1279
1280/*
1281 EmitSet - emits the tokens in the set, to, which have values low..high
1282*/
1283
1284static void EmitSet (pge_SetDesc to, unsigned int low, unsigned int high);
1285
1286/*
1287 EmitSetName - emits the tokens in the set, to, which have values low..high, using
1288 their names.
1289*/
1290
1291static void EmitSetName (pge_SetDesc to, unsigned int low, unsigned int high);
1292
1293/*
1294 EmitStopParametersAndSet - generates the stop parameters together with a set
1295 inclusion of all the symbols in set, to.
1296*/
1297
1298static void EmitStopParametersAndSet (pge_SetDesc to);
1299
1300/*
1301 EmitSetAsParameters - generates the first symbols as parameters to a set function.
1302*/
1303
1304static void EmitSetAsParameters (pge_SetDesc to);
1305
1306/*
1307 EmitStopParametersAndFollow - generates the stop parameters together with a set
1308 inclusion of all the follow symbols for subsequent
1309 sentances.
1310*/
1311
1312static void EmitStopParametersAndFollow (pge_FactorDesc f, pge_m2condition m);
1313
1314/*
1315 EmitFirstAsParameters -
1316*/
1317
1318static void EmitFirstAsParameters (pge_FactorDesc f);
1319
1320/*
1321 RecoverProduction - only encode grammer rules which are not special.
1322 Generate error recovery code.
1323*/
1324
1325static void RecoverProduction (pge_ProductionDesc p);
1326
1327/*
1328 IsWhite - returns TRUE if, ch, is a space or a tab.
1329*/
1330
1331static unsigned int IsWhite (char ch);
1332
1333/*
1334 FindStr - returns TRUE if, str, was seen inside the code hunk
1335*/
1336
1337static unsigned int FindStr (pge_CodeHunk *code, unsigned int *i, const char *str_, unsigned int _str_high);
1338
1339/*
1340 WriteUpto -
1341*/
1342
1343static void WriteUpto (pge_CodeHunk code, pge_CodeHunk upto, unsigned int limit);
1344
1345/*
1346 CheckForVar - checks for any local variables which need to be emitted during
1347 this production.
1348*/
1349
1350static void CheckForVar (pge_CodeHunk code);
1351
1352/*
1353 VarFactor -
1354*/
1355
1356static void VarFactor (pge_FactorDesc f);
1357
1358/*
1359 VarTerm -
1360*/
1361
1362static void VarTerm (pge_TermDesc t);
1363
1364/*
1365 VarExpression -
1366*/
1367
1368static void VarExpression (pge_ExpressionDesc e);
1369
1370/*
1371 VarStatement -
1372*/
1373
1374static void VarStatement (pge_StatementDesc s);
1375
1376/*
1377 VarProduction - writes out all variable declarations.
1378*/
1379
1380static void VarProduction (pge_ProductionDesc p);
1381
1382/*
1383 In - returns TRUE if token, s, is already in the set, to.
1384*/
1385
1386static unsigned int In (pge_SetDesc to, NameKey_Name s);
1387
1388/*
1389 IntersectionIsNil - given two set lists, s1, s2, return TRUE if the
1390 s1 * s2 = {}
1391*/
1392
1393static unsigned int IntersectionIsNil (pge_SetDesc s1, pge_SetDesc s2);
1394
1395/*
1396 AddSet - adds a first symbol to a production.
1397*/
1398
1399static void AddSet (pge_SetDesc *to, NameKey_Name s);
1400
1401/*
1402 OrSet -
1403*/
1404
1405static void OrSet (pge_SetDesc *to, pge_SetDesc from);
1406
1407/*
1408 CalcFirstFactor -
1409*/
1410
1411static void CalcFirstFactor (pge_FactorDesc f, pge_ProductionDesc from, pge_SetDesc *to);
1412
1413/*
1414 CalcFirstTerm -
1415*/
1416
1417static void CalcFirstTerm (pge_TermDesc t, pge_ProductionDesc from, pge_SetDesc *to);
1418
1419/*
1420 CalcFirstExpression -
1421*/
1422
1423static void CalcFirstExpression (pge_ExpressionDesc e, pge_ProductionDesc from, pge_SetDesc *to);
1424
1425/*
1426 CalcFirstStatement -
1427*/
1428
1429static void CalcFirstStatement (pge_StatementDesc s, pge_ProductionDesc from, pge_SetDesc *to);
1430
1431/*
1432 CalcFirstProduction - calculates all of the first symbols for the grammer
1433*/
1434
1435static void CalcFirstProduction (pge_ProductionDesc p, pge_ProductionDesc from, pge_SetDesc *to);
1436static void WorkOutFollowFactor (pge_FactorDesc f, pge_SetDesc *followset, pge_SetDesc after);
1437
1438/*
1439 WorkOutFollowTerm -
1440*/
1441
1442static void WorkOutFollowTerm (pge_TermDesc t, pge_SetDesc *followset, pge_SetDesc after);
1443
1444/*
1445 WorkOutFollowExpression -
1446*/
1447
1448static void WorkOutFollowExpression (pge_ExpressionDesc e, pge_SetDesc *followset, pge_SetDesc after);
1449
1450/*
1451 CollectFollow - collects the follow set from, f, into, to.
1452*/
1453
1454static void CollectFollow (pge_SetDesc *to, pge_FollowDesc f);
1455
1456/*
1457 CalcFollowFactor -
1458*/
1459
1460static void CalcFollowFactor (pge_FactorDesc f, pge_SetDesc after);
1461
1462/*
1463 CalcFollowTerm -
1464*/
1465
1466static void CalcFollowTerm (pge_TermDesc t, pge_SetDesc after);
1467
1468/*
1469 CalcFollowExpression -
1470*/
1471
1472static void CalcFollowExpression (pge_ExpressionDesc e, pge_SetDesc after);
1473
1474/*
1475 CalcFollowStatement - given a bnf statement generate the follow set.
1476*/
1477
1478static void CalcFollowStatement (pge_StatementDesc s);
1479
1480/*
1481 CalcFollowProduction -
1482*/
1483
1484static void CalcFollowProduction (pge_ProductionDesc p);
1485
1486/*
1487 CalcEpsilonFactor -
1488*/
1489
1490static void CalcEpsilonFactor (pge_FactorDesc f);
1491
1492/*
1493 CalcEpsilonTerm -
1494*/
1495
1496static void CalcEpsilonTerm (pge_TermDesc t);
1497
1498/*
1499 CalcEpsilonExpression -
1500*/
1501
1502static void CalcEpsilonExpression (pge_ExpressionDesc e);
1503
1504/*
1505 CalcEpsilonStatement - given a bnf statement generate the follow set.
1506*/
1507
1508static void CalcEpsilonStatement (pge_StatementDesc s);
1509
1510/*
1511 CalcEpsilonProduction -
1512*/
1513
1514static void CalcEpsilonProduction (pge_ProductionDesc p);
1515
1516/*
1517 CalcReachEndFactor -
1518*/
1519
1520static pge_TraverseResult CalcReachEndFactor (pge_FactorDesc f);
1521
1522/*
1523 CalcReachEndTerm -
1524*/
1525
1526static pge_TraverseResult CalcReachEndTerm (pge_TermDesc t);
1527
1528/*
1529 CalcReachEndExpression -
1530*/
1531
1532static void CalcReachEndExpression (pge_ExpressionDesc e);
1533
1534/*
1535 CalcReachEndStatement -
1536*/
1537
1538static void CalcReachEndStatement (pge_StatementDesc s);
1539
1540/*
1541 CalcReachEndStatement -
1542*/
1543
1544static void stop (void);
1545
1546/*
1547 CalcReachEndProduction -
1548*/
1549
1550static void CalcReachEndProduction (pge_ProductionDesc p);
1551
1552/*
1553 EmptyFactor -
1554*/
1555
1556static unsigned int EmptyFactor (pge_FactorDesc f);
1557
1558/*
1559 EmptyTerm - returns TRUE if the term maybe empty.
1560*/
1561
1562static unsigned int EmptyTerm (pge_TermDesc t);
1563
1564/*
1565 EmptyExpression -
1566*/
1567
1568static unsigned int EmptyExpression (pge_ExpressionDesc e);
1569
1570/*
1571 EmptyStatement - returns TRUE if statement, s, is empty.
1572*/
1573
1574static unsigned int EmptyStatement (pge_StatementDesc s);
1575
1576/*
1577 EmptyProduction - returns if production, p, maybe empty.
1578*/
1579
1580static unsigned int EmptyProduction (pge_ProductionDesc p);
1581
1582/*
1583 EmitFDLNotice -
1584*/
1585
1586static void EmitFDLNotice (void);
1587
1588/*
1589 EmitRules - generates the BNF rules.
1590*/
1591
1592static void EmitRules (void);
1593
1594/*
1595 DescribeElement -
1596*/
1597
1598static void DescribeElement (unsigned int name);
1599
1600/*
1601 EmitInTestStop - construct a test for stop element, name.
1602*/
1603
1604static void EmitInTestStop (NameKey_Name name);
1605
1606/*
1607 DescribeStopElement -
1608*/
1609
1610static void DescribeStopElement (unsigned int name);
1611
1612/*
1613 EmitDescribeStop -
1614*/
1615
1616static void EmitDescribeStop (void);
1617
1618/*
1619 EmitDescribeError -
1620*/
1621
1622static void EmitDescribeError (void);
1623
1624/*
1625 EmitSetTypes - write out the set types used during error recovery
1626*/
1627
1628static void EmitSetTypes (void);
1629
1630/*
1631 EmitSupport - generates the support routines.
1632*/
1633
1634static void EmitSupport (void);
1635
1636/*
1637 DisposeSetDesc - dispose of the set list, s.
1638*/
1639
1640static void DisposeSetDesc (pge_SetDesc *s);
1641
1642/*
1643 OptionalFactor -
1644*/
1645
1646static unsigned int OptionalFactor (pge_FactorDesc f);
1647
1648/*
1649 OptionalTerm - returns TRUE if the term maybe empty.
1650*/
1651
1652static unsigned int OptionalTerm (pge_TermDesc t);
1653
1654/*
1655 OptionalExpression -
1656*/
1657
1658static unsigned int OptionalExpression (pge_ExpressionDesc e);
1659
1660/*
1661 OptionalStatement - returns FALSE if statement, s, does not have a optional ambiguity.
1662*/
1663
1664static unsigned int OptionalStatement (pge_StatementDesc s);
1665
1666/*
1667 OptionalProduction -
1668*/
1669
1670static unsigned int OptionalProduction (pge_ProductionDesc p);
1671
1672/*
1673 CheckFirstFollow -
1674*/
1675
1676static unsigned int CheckFirstFollow (pge_FactorDesc f, pge_FactorDesc after);
1677
1678/*
1679 ConstrainedEmptyFactor -
1680*/
1681
1682static unsigned int ConstrainedEmptyFactor (pge_FactorDesc f);
1683
1684/*
1685 ConstrainedEmptyTerm - returns TRUE if the term maybe empty.
1686*/
1687
1688static unsigned int ConstrainedEmptyTerm (pge_TermDesc t);
1689
1690/*
1691 ConstrainedEmptyExpression -
1692*/
1693
1694static unsigned int ConstrainedEmptyExpression (pge_ExpressionDesc e);
1695
1696/*
1697 ConstrainedEmptyStatement - returns FALSE if statement, s, does not have a optional ambiguity.
1698*/
1699
1700static unsigned int ConstrainedEmptyStatement (pge_StatementDesc s);
1701
1702/*
1703 ConstrainedEmptyProduction - returns TRUE if a problem exists with, p.
1704*/
1705
1706static unsigned int ConstrainedEmptyProduction (pge_ProductionDesc p);
1707
1708/*
1709 TestForLALR1 -
1710*/
1711
1712static void TestForLALR1 (pge_ProductionDesc p);
1713
1714/*
1715 DoEpsilon - runs the epsilon interrelated rules
1716*/
1717
1718static void DoEpsilon (pge_ProductionDesc p);
1719
1720/*
1721 CheckComplete - checks that production, p, is complete.
1722*/
1723
1724static void CheckComplete (pge_ProductionDesc p);
1725
1726/*
1727 PostProcessRules - backpatch the ident to rule definitions and emit comments and code.
1728*/
1729
1730static void PostProcessRules (void);
1731
1732/*
1733 DisplayHelp - display a summary help and then exit (0).
1734*/
1735
1736static void DisplayHelp (void);
1737
1738/*
1739 ParseArgs -
1740*/
1741
1742static void ParseArgs (void);
1743
1744/*
1745 Init - initialize the modules data structures
1746*/
1747
1748static void Init (void);
1749
1750/*
1751 DescribeStop - issues a message explaining what tokens were expected
1752*/
1753
1754static DynamicStrings_String DescribeStop (pge_SetOfStop stopset);
1755
1756/*
1757 DescribeError - issues a message explaining what tokens were expected
1758*/
1759
1760static void DescribeError (void);
1761
1762/*
1763 AddEntry - adds an entry into, t, containing [def:value].
1764*/
1765
1766static void AddEntry (SymbolKey_SymbolTree *t, NameKey_Name def, NameKey_Name value);
1767
1768/*
1769 Format1 - converts string, src, into, dest, together with encapsulated
1770 entity, n. It only formats the first %s or %d with n.
1771*/
1772
1773static void Format1 (const char *src_, unsigned int _src_high, unsigned int n, char *dest, unsigned int _dest_high);
1774
1775/*
1776 WarnError1 -
1777*/
1778
1779static void WarnError1 (const char *a_, unsigned int _a_high, unsigned int n);
1780
1781/*
1782 PrettyFollow -
1783*/
1784
1785static void PrettyFollow (const char *start_, unsigned int _start_high, const char *end_, unsigned int _end_high, pge_FollowDesc f);
1786
1787/*
1788 NewFollow - creates a new follow descriptor and returns the data structure.
1789*/
1790
1791static pge_FollowDesc NewFollow (void);
1792
1793/*
1794 AssignEpsilon - assigns the epsilon value and sets the epsilon to value,
1795 providing condition is TRUE.
1796*/
1797
1798static void AssignEpsilon (unsigned int condition, pge_FollowDesc f, pge_TraverseResult value);
1799
1800/*
1801 GetEpsilon - returns the value of epsilon
1802*/
1803
1804static pge_TraverseResult GetEpsilon (pge_FollowDesc f);
1805
1806/*
1807 AssignReachEnd - assigns the reachend value providing that, condition, is TRUE.
1808*/
1809
1810static void AssignReachEnd (unsigned int condition, pge_FollowDesc f, pge_TraverseResult value);
1811
1812/*
1813 GetReachEnd - returns the value of reachend
1814*/
1815
1816static pge_TraverseResult GetReachEnd (pge_FollowDesc f);
1817
1818/*
1819 AssignFollow - assigns the follow set and sets the calcfollow to TRUE.
1820*/
1821
1822static void AssignFollow (pge_FollowDesc f, pge_SetDesc s);
1823
1824/*
1825 GetFollow - returns the follow set.
1826*/
1827
1828static pge_SetDesc GetFollow (pge_FollowDesc f);
1829
1830/*
1831 NewProduction - creates a new production and returns the data structure.
1832*/
1833
1834static pge_ProductionDesc NewProduction (void);
1835
1836/*
1837 NewFactor -
1838*/
1839
1840static pge_FactorDesc NewFactor (void);
1841
1842/*
1843 NewTerm - returns a new term.
1844*/
1845
1846static pge_TermDesc NewTerm (void);
1847
1848/*
1849 NewExpression - returns a new expression.
1850*/
1851
1852static pge_ExpressionDesc NewExpression (void);
1853
1854/*
1855 NewStatement - returns a new statement.
1856*/
1857
1858static pge_StatementDesc NewStatement (void);
1859
1860/*
1861 NewSetDesc - creates a new set description and returns the data structure.
1862*/
1863
1864static pge_SetDesc NewSetDesc (void);
1865
1866/*
1867 NewCodeDesc - creates a new code descriptor and initializes all fields to zero.
1868*/
1869
1870static pge_CodeDesc NewCodeDesc (void);
1871
1872/*
1873 CodeFragmentPrologue - consumes code text up to a "%" after a newline.
1874*/
1875
1876static void CodeFragmentPrologue (void);
1877
1878/*
1879 CodeFragmentEpilogue - consumes code text up to a "%" after a newline.
1880*/
1881
1882static void CodeFragmentEpilogue (void);
1883
1884/*
1885 CodeFragmentDeclaration - consumes code text up to a "%" after a newline.
1886*/
1887
1888static void CodeFragmentDeclaration (void);
1889
1890/*
1891 GetCodeFragment - collects the code fragment up until ^ %
1892*/
1893
1894static void GetCodeFragment (pge_CodeHunk *h);
1895
1896/*
1897 WriteCodeHunkList - writes the CodeHunk list in the correct order.
1898*/
1899
1900static void WriteCodeHunkList (pge_CodeHunk l);
1901
1902/*
1903 WriteIndent - writes, n, spaces.
1904*/
1905
1906static void WriteIndent (unsigned int n);
1907
1908/*
1909 CheckWrite -
1910*/
1911
1912static void CheckWrite (char ch, unsigned int *curpos, unsigned int left, unsigned int *seentext);
1913
1914/*
1915 WriteStringIndent - writes a string but it will try and remove upto indent spaces
1916 if they exist.
1917*/
1918
1919static void WriteStringIndent (const char *a_, unsigned int _a_high, unsigned int indent, unsigned int *curpos, unsigned int left, unsigned int *seentext);
1920
1921/*
1922 WriteCodeHunkListIndent - writes the CodeHunk list in the correct order
1923 but it removes up to indent spaces if they exist.
1924*/
1925
1926static void WriteCodeHunkListIndent (pge_CodeHunk l, unsigned int indent, unsigned int *curpos, unsigned int left, unsigned int *seentext);
1927
1928/*
1929 Add - adds a character to a code hunk and creates another code hunk if necessary.
1930*/
1931
1932static pge_CodeHunk Add (pge_CodeHunk *p, char ch, unsigned int *i);
1933
1934/*
1935 ConsHunk - combine two possible code hunks.
1936*/
1937
1938static void ConsHunk (pge_CodeHunk *p, pge_CodeHunk q);
1939
1940/*
1941 GetName - returns the next symbol which is checked for a legal name.
1942*/
1943
1944static NameKey_Name GetName (void);
1945
1946/*
1947 SyntaxError - after a syntax error we skip all tokens up until we reach
1948 a stop symbol.
1949*/
1950
1951static void SyntaxError (pge_SetOfStop stop);
1952
1953/*
1954 SyntaxCheck -
1955*/
1956
1957static void SyntaxCheck (pge_SetOfStop stop);
1958
1959/*
1960 Expect -
1961*/
1962
1963static void Expect (bnflex_TokenType t, pge_SetOfStop stop);
1964
1965/*
1966 Ident - error checking varient of Ident
1967*/
1968
1969static void Ident (pge_SetOfStop stop);
1970
1971/*
1972 Modula2Code - error checking varient of Modula2Code
1973*/
1974
1975static void Modula2Code (pge_SetOfStop stop);
1976
1977/*
1978 StartModName := % ModuleName := GetName() ; ignore begintok CodeFragmentPrologue % =:
1979*/
1980
1981static void StartModName (pge_SetOfStop stop);
1982
1983/*
1984 EndModName :=
1985*/
1986
1987static void EndModName (pge_SetOfStop stop);
1988
1989/*
1990 DoDeclaration := % CodeFragmentDeclaration % =:
1991*/
1992
1993static void DoDeclaration (pge_SetOfStop stop);
1994
1995/*
1996 CollectLiteral :=
1997 % LastLiteral := GetCurrentToken() ;
1998 AdvanceToken ; %
1999
2000
2001 first symbols:literaltok
2002
2003 cannot reachend
2004*/
2005
2006static void CollectLiteral (pge_SetOfStop stopset);
2007
2008/*
2009 CollectTok :=
2010 % CurrentSetDesc := NewSetDesc() ;
2011 WITH CurrentSetDesc^ DO
2012 type := tokel ;
2013 string := GetCurrentToken() ;
2014 END ;
2015 IF NOT ContainsSymKey(Values, GetCurrentToken())
2016 THEN
2017 AddEntry(Values, GetCurrentToken(), LargestValue) ;
2018 AddEntry(ReverseValues, Name(LargestValue), GetCurrentToken()) ;
2019 AddEntry(Aliases, GetCurrentToken(), GetCurrentToken()) ;
2020 AddEntry(ReverseAliases, GetCurrentToken(), GetCurrentToken()) ;
2021 INC(LargestValue)
2022 END ;
2023 AdvanceToken() ; %
2024
2025
2026 first symbols:identtok
2027
2028 cannot reachend
2029*/
2030
2031static void CollectTok (pge_SetOfStop stopset);
2032
2033/*
2034 DefineToken :=
2035 % AddEntry(Aliases, LastLiteral, GetCurrentToken()) ;
2036 AddEntry(ReverseAliases, GetCurrentToken(), LastLiteral) ;
2037 AddEntry(Values, GetCurrentToken(), LargestValue) ;
2038 AddEntry(ReverseValues, Name(LargestValue), GetCurrentToken()) ;
2039 INC(LargestValue) ;
2040 AdvanceToken ; %
2041
2042
2043 first symbols:identtok
2044
2045 cannot reachend
2046*/
2047
2048static void DefineToken (pge_SetOfStop stopset);
2049
2050/*
2051 Rules := '%' 'rules' { Defs } ExtBNF
2052
2053 first symbols:codetok
2054
2055 cannot reachend
2056*/
2057
2058static void Rules (pge_SetOfStop stopset);
2059
2060/*
2061 Special := Ident
2062 % VAR p: ProductionDesc ; %
2063
2064 % p := NewProduction() ;
2065 p^.statement := NewStatement() ;
2066 p^.statement^.followinfo^.calcfollow := TRUE ;
2067 p^.statement^.followinfo^.epsilon := false ;
2068 p^.statement^.followinfo^.reachend := false ;
2069 p^.statement^.ident := CurrentIdent ;
2070 p^.statement^.expr := NIL ;
2071 p^.firstsolved := TRUE ;
2072 p^.followinfo^.calcfollow := TRUE ;
2073 p^.followinfo^.epsilon := false ;
2074 p^.followinfo^.reachend := false %
2075 First Follow [ 'epsilon'
2076 % p^.statement^.followinfo^.epsilon := true ; these are not used - but they are displayed when debugging
2077 p^.statement^.followinfo^.reachend := true ;
2078 p^.followinfo^.epsilon := true ;
2079 p^.followinfo^.reachend := true
2080 %
2081 ] [ Literal
2082 % p^.description := LastLiteral %
2083 ]
2084
2085 first symbols:identtok
2086
2087 cannot reachend
2088*/
2089
2090static void Special (pge_SetOfStop stopset);
2091
2092/*
2093 Factor := '%' Modula2Code '%' |
2094 Ident
2095 % WITH CurrentFactor^ DO
2096 type := id ;
2097 ident := CurrentIdent
2098 END ; %
2099 | Literal
2100 % WITH CurrentFactor^ DO
2101 type := lit ;
2102 string := LastLiteral ;
2103 IF GetSymKey(Aliases, LastLiteral)=NulName
2104 THEN
2105 WarnError1('no token defined for literal %s', LastLiteral)
2106 END
2107 END ; %
2108 | '{'
2109 % WITH CurrentFactor^ DO
2110 type := mult ;
2111 expr := NewExpression() ;
2112 CurrentExpression := expr ;
2113 END ; %
2114 Expression '}' | '['
2115 % WITH CurrentFactor^ DO
2116 type := opt ;
2117 expr := NewExpression() ;
2118 CurrentExpression := expr ;
2119 END ; %
2120 Expression ']' | '('
2121 % WITH CurrentFactor^ DO
2122 type := sub ;
2123 expr := NewExpression() ;
2124 CurrentExpression := expr ;
2125 END ; %
2126 Expression ')'
2127
2128 first symbols:dquotetok, squotetok, lparatok, lsparatok, lcparatok, identtok, codetok
2129
2130 cannot reachend
2131*/
2132
2133static void Factor (pge_SetOfStop stopset);
2134
2135/*
2136 Statement :=
2137 % VAR i: IdentDesc ; %
2138 Ident
2139 % VAR p: ProductionDesc ; %
2140
2141 % p := FindDefinition(CurrentIdent^.name) ;
2142 IF p=NIL
2143 THEN
2144 p := NewProduction()
2145 ELSE
2146 IF NOT ((p^.statement=NIL) OR (p^.statement^.expr=NIL))
2147 THEN
2148 WarnError1('already declared rule %s', CurrentIdent^.name)
2149 END
2150 END ;
2151 i := CurrentIdent ; %
2152 ':='
2153 % VAR e: ExpressionDesc ; %
2154
2155 % e := NewExpression() ;
2156 CurrentExpression := e ; %
2157
2158 % VAR s: StatementDesc ; %
2159
2160 % s := NewStatement() ;
2161 WITH s^ DO
2162 ident := i ;
2163 expr := e
2164 END ; %
2165 Expression
2166 % p^.statement := s ; %
2167 '=:'
2168
2169 first symbols:identtok
2170
2171 cannot reachend
2172*/
2173
2174static void Statement (pge_SetOfStop stopset);
2175
2176/*
2177 Defs := 'special' Special | 'token' Token |
2178 'error' ErrorProcedures |
2179 'tokenfunc' TokenProcedure |
2180 'symfunc' SymProcedure
2181
2182 first symbols:symfunctok, tfunctok, errortok, tokentok, specialtok
2183
2184 cannot reachend
2185*/
2186
2187static void Defs (pge_SetOfStop stopset);
2188
2189/*
2190 ExtBNF := 'BNF' { Production } 'FNB'
2191
2192 first symbols:BNFtok
2193
2194 cannot reachend
2195*/
2196
2197static void ExtBNF (pge_SetOfStop stopset);
2198
2199/*
2200 Main := Header Decls Footer Rules
2201
2202 first symbols:codetok
2203
2204 cannot reachend
2205*/
2206
2207static void Main (pge_SetOfStop stopset);
2208
2209/*
2210 Header := '%' 'module' StartModName
2211
2212 first symbols:codetok
2213
2214 cannot reachend
2215*/
2216
2217static void Header (pge_SetOfStop stopset);
2218
2219/*
2220 Decls := '%' 'declaration' DoDeclaration
2221
2222 first symbols:codetok
2223
2224 cannot reachend
2225*/
2226
2227static void Decls (pge_SetOfStop stopset);
2228
2229/*
2230 Footer := '%' 'module' EndModName
2231
2232 first symbols:codetok
2233
2234 cannot reachend
2235*/
2236
2237static void Footer (pge_SetOfStop stopset);
2238
2239/*
2240 First := 'first' '{' { LitOrTokenOrIdent
2241 % WITH CurrentSetDesc^ DO
2242 next := TailProduction^.first ;
2243 END ;
2244 TailProduction^.first := CurrentSetDesc
2245 %
2246 } '}'
2247
2248 first symbols:firsttok
2249
2250 cannot reachend
2251*/
2252
2253static void First (pge_SetOfStop stopset);
2254
2255/*
2256 Follow := 'follow' '{' { LitOrTokenOrIdent
2257 % WITH CurrentSetDesc^ DO
2258 next := TailProduction^.followinfo^.follow ;
2259 END ;
2260 TailProduction^.followinfo^.follow := CurrentSetDesc
2261 %
2262 } '}'
2263
2264 first symbols:followtok
2265
2266 cannot reachend
2267*/
2268
2269static void Follow (pge_SetOfStop stopset);
2270
2271/*
2272 LitOrTokenOrIdent := Literal
2273 % CurrentSetDesc := NewSetDesc() ;
2274 WITH CurrentSetDesc^ DO
2275 type := litel ;
2276 string := LastLiteral ;
2277 END ;
2278 %
2279 | '<' CollectTok '>' |
2280 Ident
2281 % CurrentSetDesc := NewSetDesc() ;
2282 WITH CurrentSetDesc^ DO
2283 type := idel ;
2284 ident := CurrentIdent ;
2285 END ;
2286 %
2287
2288
2289 first symbols:dquotetok, squotetok, identtok, lesstok
2290
2291 cannot reachend
2292*/
2293
2294static void LitOrTokenOrIdent (pge_SetOfStop stopset);
2295
2296/*
2297 Literal := '"' CollectLiteral '"' |
2298 "'" CollectLiteral "'"
2299
2300 first symbols:squotetok, dquotetok
2301
2302 cannot reachend
2303*/
2304
2305static void Literal (pge_SetOfStop stopset);
2306
2307/*
2308 Token := Literal DefineToken
2309
2310 first symbols:dquotetok, squotetok
2311
2312 cannot reachend
2313*/
2314
2315static void Token (pge_SetOfStop stopset);
2316
2317/*
2318 ErrorProcedures := Literal
2319 % ErrorProcArray := LastLiteral %
2320 Literal
2321 % ErrorProcString := LastLiteral %
2322
2323
2324 first symbols:dquotetok, squotetok
2325
2326 cannot reachend
2327*/
2328
2329static void ErrorProcedures (pge_SetOfStop stopset);
2330
2331/*
2332 TokenProcedure := Literal
2333 % TokenTypeProc := LastLiteral %
2334
2335
2336 first symbols:dquotetok, squotetok
2337
2338 cannot reachend
2339*/
2340
2341static void TokenProcedure (pge_SetOfStop stopset);
2342
2343/*
2344 SymProcedure := Literal
2345 % SymIsProc := LastLiteral %
2346
2347
2348 first symbols:dquotetok, squotetok
2349
2350 cannot reachend
2351*/
2352
2353static void SymProcedure (pge_SetOfStop stopset);
2354
2355/*
2356 Production := Statement
2357
2358 first symbols:identtok
2359
2360 cannot reachend
2361*/
2362
2363static void Production (pge_SetOfStop stopset);
2364
2365/*
2366 Expression :=
2367 % VAR t1, t2: TermDesc ;
2368 e : ExpressionDesc ; %
2369
2370 % e := CurrentExpression ;
2371 t1 := NewTerm() ;
2372 CurrentTerm := t1 ; %
2373 Term
2374 % e^.term := t1 ; %
2375 { '|'
2376 % t2 := NewTerm() ;
2377 CurrentTerm := t2 %
2378 Term
2379 % t1^.next := t2 ;
2380 t1 := t2 %
2381 }
2382
2383 first symbols:dquotetok, squotetok, lparatok, lsparatok, lcparatok, identtok, codetok
2384
2385 cannot reachend
2386*/
2387
2388static void Expression (pge_SetOfStop stopset);
2389
2390/*
2391 Term :=
2392 % VAR t1: TermDesc ; f1, f2: FactorDesc ; %
2393
2394 % CurrentFactor := NewFactor() ;
2395 f1 := CurrentFactor ;
2396 t1 := CurrentTerm ; %
2397 Factor
2398 % t1^.factor := f1 ;
2399 f2 := NewFactor() ;
2400 CurrentFactor := f2 %
2401 { Factor
2402 % f1^.next := f2 ;
2403 f1 := f2 ;
2404 f2 := NewFactor() ;
2405 CurrentFactor := f2 ; %
2406 }
2407
2408 first symbols:squotetok, dquotetok, codetok, identtok, lcparatok, lsparatok, lparatok
2409
2410 cannot reachend
2411*/
2412
2413static void Term (pge_SetOfStop stopset);
2414
2415/*
2416 GetDefinitionName - returns the name of the rule inside, p.
2417*/
2418
2419static NameKey_Name GetDefinitionName (pge_ProductionDesc p);
2420
2421/*
2422 FindDefinition - searches and returns the rule which defines, n.
2423*/
2424
2425static pge_ProductionDesc FindDefinition (NameKey_Name n);
2426
2427/*
2428 BackPatchIdent - found an ident, i, we must look for the corresponding rule and
2429 set the definition accordingly.
2430*/
2431
2432static void BackPatchIdent (pge_IdentDesc i);
2433
2434/*
2435 BackPatchFactor - runs through the factor looking for an ident
2436*/
2437
2438static void BackPatchFactor (pge_FactorDesc f);
2439
2440/*
2441 BackPatchTerm - runs through all terms to find idents.
2442*/
2443
2444static void BackPatchTerm (pge_TermDesc t);
2445
2446/*
2447 BackPatchExpression - runs through the term to find any idents.
2448*/
2449
2450static void BackPatchExpression (pge_ExpressionDesc e);
2451
2452/*
2453 BackPatchSet -
2454*/
2455
2456static void BackPatchSet (pge_SetDesc s);
2457
2458/*
2459 BackPatchIdentToDefinitions - search through all the rules and add a link from any ident
2460 to the definition.
2461*/
2462
2463static void BackPatchIdentToDefinitions (pge_ProductionDesc d);
2464
2465/*
2466 CalculateFirstAndFollow -
2467*/
2468
2469static void CalculateFirstAndFollow (pge_ProductionDesc p);
2470
2471/*
2472 ForeachRuleDo -
2473*/
2474
2475static void ForeachRuleDo (pge_DoProcedure p);
2476
2477/*
2478 WhileNotCompleteDo -
2479*/
2480
2481static void WhileNotCompleteDo (pge_DoProcedure p);
2482
2483/*
2484 NewLine - generate a newline and indent.
2485*/
2486
2487static void NewLine (unsigned int Left);
2488
2489/*
2490 CheckNewLine -
2491*/
2492
2493static void CheckNewLine (unsigned int Left);
2494
2495/*
2496 IndentString - writes out a string with a preceeding indent.
2497*/
2498
2499static void IndentString (const char *a_, unsigned int _a_high);
2500
2501/*
2502 KeyWord - writes out a keywork with optional formatting directives.
2503*/
2504
2505static void KeyWord (NameKey_Name n);
2506
2507/*
2508 PrettyPara -
2509*/
2510
2511static void PrettyPara (const char *c1_, unsigned int _c1_high, const char *c2_, unsigned int _c2_high, pge_ExpressionDesc e, unsigned int Left);
2512
2513/*
2514 WriteKeyTexinfo -
2515*/
2516
2517static void WriteKeyTexinfo (NameKey_Name s);
2518
2519/*
2520 PrettyCommentFactor -
2521*/
2522
2523static void PrettyCommentFactor (pge_FactorDesc f, unsigned int Left);
2524
2525/*
2526 PeepTerm - returns the length of characters in term.
2527*/
2528
2529static unsigned int PeepTerm (pge_TermDesc t);
2530
2531/*
2532 PeepExpression - returns the length of the expression.
2533*/
2534
2535static unsigned int PeepExpression (pge_ExpressionDesc e);
2536
2537/*
2538 PeepFactor - returns the length of character in the factor
2539*/
2540
2541static unsigned int PeepFactor (pge_FactorDesc f);
2542
2543/*
2544 PrettyCommentTerm -
2545*/
2546
2547static void PrettyCommentTerm (pge_TermDesc t, unsigned int Left);
2548
2549/*
2550 PrettyCommentExpression -
2551*/
2552
2553static void PrettyCommentExpression (pge_ExpressionDesc e, unsigned int Left);
2554
2555/*
2556 PrettyCommentStatement -
2557*/
2558
2559static void PrettyCommentStatement (pge_StatementDesc s, unsigned int Left);
2560
2561/*
2562 PrettyCommentProduction - generates the comment for rule, p.
2563*/
2564
2565static void PrettyCommentProduction (pge_ProductionDesc p);
2566
2567/*
2568 PrettyPrintProduction - pretty prints the ebnf rule, p.
2569*/
2570
2571static void PrettyPrintProduction (pge_ProductionDesc p);
2572
2573/*
2574 EmitFileLineTag - emits a line and file tag using the C preprocessor syntax.
2575*/
2576
2577static void EmitFileLineTag (unsigned int line);
2578
2579/*
2580 EmitRule - generates a comment and code for rule, p.
2581*/
2582
2583static void EmitRule (pge_ProductionDesc p);
2584
2585/*
2586 CodeCondition -
2587*/
2588
2589static void CodeCondition (pge_m2condition m);
2590
2591/*
2592 CodeThenDo - codes a "THEN" or "DO" depending upon, m.
2593*/
2594
2595static void CodeThenDo (pge_m2condition m);
2596
2597/*
2598 CodeElseEnd - builds an ELSE END statement using string, end.
2599*/
2600
2601static void CodeElseEnd (const char *end_, unsigned int _end_high, unsigned int consumed, pge_FactorDesc f, unsigned int inopt);
2602
2603/*
2604 CodeEnd - codes a "END" depending upon, m.
2605*/
2606
2607static void CodeEnd (pge_m2condition m, pge_TermDesc t, unsigned int consumed, pge_FactorDesc f, unsigned int inopt);
2608
2609/*
2610 EmitNonVarCode - writes out, code, providing it is not a variable declaration.
2611*/
2612
2613static void EmitNonVarCode (pge_CodeDesc code, unsigned int curpos, unsigned int left);
2614
2615/*
2616 ChainOn -
2617*/
2618
2619static pge_FactorDesc ChainOn (pge_FactorDesc codeStack, pge_FactorDesc f);
2620
2621/*
2622 FlushCode -
2623*/
2624
2625static void FlushCode (pge_FactorDesc *codeStack);
2626
2627/*
2628 CodeFactor -
2629*/
2630
2631static void CodeFactor (pge_FactorDesc f, pge_TermDesc t, pge_m2condition l, pge_m2condition n, unsigned int inopt, unsigned int inwhile, unsigned int consumed, pge_FactorDesc codeStack);
2632
2633/*
2634 CodeTerm -
2635*/
2636
2637static void CodeTerm (pge_TermDesc t, pge_m2condition m, unsigned int inopt, unsigned int inwhile, unsigned int consumed, pge_FactorDesc codeStack);
2638
2639/*
2640 CodeExpression -
2641*/
2642
2643static void CodeExpression (pge_ExpressionDesc e, pge_m2condition m, unsigned int inopt, unsigned int inwhile, unsigned int consumed, pge_FactorDesc codeStack);
2644
2645/*
2646 CodeStatement -
2647*/
2648
2649static void CodeStatement (pge_StatementDesc s, pge_m2condition m);
2650
2651/*
2652 CodeProduction - only encode grammer rules which are not special.
2653*/
2654
2655static void CodeProduction (pge_ProductionDesc p);
2656
2657/*
2658 RecoverCondition -
2659*/
2660
2661static void RecoverCondition (pge_m2condition m);
2662
2663/*
2664 ConditionIndent - returns the number of spaces indentation created via, m.
2665*/
2666
2667static unsigned int ConditionIndent (pge_m2condition m);
2668
2669/*
2670 WriteGetTokenType - writes out the method of determining the token type.
2671*/
2672
2673static void WriteGetTokenType (void);
2674
2675/*
2676 NumberOfElements - returns the number of elements in set, to, which lie between low..high
2677*/
2678
2679static unsigned int NumberOfElements (pge_SetDesc to, unsigned int low, unsigned int high);
2680
2681/*
2682 WriteElement - writes the literal name for element, e.
2683*/
2684
2685static void WriteElement (unsigned int e);
2686
2687/*
2688 EmitIsInSet - writes out the equivalent of GetTokenType() IN { toset }
2689*/
2690
2691static void EmitIsInSet (pge_SetDesc to, NameKey_Name low, NameKey_Name high);
2692
2693/*
2694 EmitIsInSubSet - writes out a test to see whether GetTokenype() is in { subset }
2695*/
2696
2697static void EmitIsInSubSet (pge_SetDesc to, unsigned int low, unsigned int high);
2698
2699/*
2700 EmitIsInFirst -
2701*/
2702
2703static void EmitIsInFirst (pge_SetDesc to, pge_m2condition m);
2704static void FlushRecoverCode (pge_FactorDesc *codeStack);
2705
2706/*
2707 RecoverFactor -
2708*/
2709
2710static void RecoverFactor (pge_FactorDesc f, pge_m2condition m, pge_FactorDesc codeStack);
2711
2712/*
2713 OptExpSeen - returns TRUE if we can see an optional expression in the factor.
2714 This is not the same as epsilon. Example { '+' } matches epsilon as
2715 well as { '+' | '-' } but OptExpSeen returns TRUE in the second case
2716 and FALSE in the first.
2717*/
2718
2719static unsigned int OptExpSeen (pge_FactorDesc f);
2720
2721/*
2722 RecoverTerm -
2723*/
2724
2725static void RecoverTerm (pge_TermDesc t, pge_m2condition new_, pge_m2condition old);
2726
2727/*
2728 RecoverExpression -
2729*/
2730
2731static void RecoverExpression (pge_ExpressionDesc e, pge_m2condition new_, pge_m2condition old);
2732
2733/*
2734 RecoverStatement -
2735*/
2736
2737static void RecoverStatement (pge_StatementDesc s, pge_m2condition m);
2738
2739/*
2740 EmitFirstFactor - generate a list of all first tokens between the range: low..high.
2741*/
2742
2743static void EmitFirstFactor (pge_FactorDesc f, unsigned int low, unsigned int high);
2744
2745/*
2746 EmitUsed -
2747*/
2748
2749static void EmitUsed (unsigned int wordno);
2750
2751/*
2752 EmitStopParameters - generate the stop set.
2753*/
2754
2755static void EmitStopParameters (unsigned int FormalParameters);
2756
2757/*
2758 IsBetween - returns TRUE if the value of the token, string, is
2759 in the range: low..high
2760*/
2761
2762static unsigned int IsBetween (NameKey_Name string, unsigned int low, unsigned int high);
2763
2764/*
2765 IsEmptySet - returns TRUE if no elements exist in set, to, with values, low..high.
2766*/
2767
2768static unsigned int IsEmptySet (pge_SetDesc to, unsigned int low, unsigned int high);
2769
2770/*
2771 EmitSet - emits the tokens in the set, to, which have values low..high
2772*/
2773
2774static void EmitSet (pge_SetDesc to, unsigned int low, unsigned int high);
2775
2776/*
2777 EmitSetName - emits the tokens in the set, to, which have values low..high, using
2778 their names.
2779*/
2780
2781static void EmitSetName (pge_SetDesc to, unsigned int low, unsigned int high);
2782
2783/*
2784 EmitStopParametersAndSet - generates the stop parameters together with a set
2785 inclusion of all the symbols in set, to.
2786*/
2787
2788static void EmitStopParametersAndSet (pge_SetDesc to);
2789
2790/*
2791 EmitSetAsParameters - generates the first symbols as parameters to a set function.
2792*/
2793
2794static void EmitSetAsParameters (pge_SetDesc to);
2795
2796/*
2797 EmitStopParametersAndFollow - generates the stop parameters together with a set
2798 inclusion of all the follow symbols for subsequent
2799 sentances.
2800*/
2801
2802static void EmitStopParametersAndFollow (pge_FactorDesc f, pge_m2condition m);
2803
2804/*
2805 EmitFirstAsParameters -
2806*/
2807
2808static void EmitFirstAsParameters (pge_FactorDesc f);
2809
2810/*
2811 RecoverProduction - only encode grammer rules which are not special.
2812 Generate error recovery code.
2813*/
2814
2815static void RecoverProduction (pge_ProductionDesc p);
2816
2817/*
2818 IsWhite - returns TRUE if, ch, is a space or a tab.
2819*/
2820
2821static unsigned int IsWhite (char ch);
2822
2823/*
2824 FindStr - returns TRUE if, str, was seen inside the code hunk
2825*/
2826
2827static unsigned int FindStr (pge_CodeHunk *code, unsigned int *i, const char *str_, unsigned int _str_high);
2828
2829/*
2830 WriteUpto -
2831*/
2832
2833static void WriteUpto (pge_CodeHunk code, pge_CodeHunk upto, unsigned int limit);
2834
2835/*
2836 CheckForVar - checks for any local variables which need to be emitted during
2837 this production.
2838*/
2839
2840static void CheckForVar (pge_CodeHunk code);
2841
2842/*
2843 VarFactor -
2844*/
2845
2846static void VarFactor (pge_FactorDesc f);
2847
2848/*
2849 VarTerm -
2850*/
2851
2852static void VarTerm (pge_TermDesc t);
2853
2854/*
2855 VarExpression -
2856*/
2857
2858static void VarExpression (pge_ExpressionDesc e);
2859
2860/*
2861 VarStatement -
2862*/
2863
2864static void VarStatement (pge_StatementDesc s);
2865
2866/*
2867 VarProduction - writes out all variable declarations.
2868*/
2869
2870static void VarProduction (pge_ProductionDesc p);
2871
2872/*
2873 In - returns TRUE if token, s, is already in the set, to.
2874*/
2875
2876static unsigned int In (pge_SetDesc to, NameKey_Name s);
2877
2878/*
2879 IntersectionIsNil - given two set lists, s1, s2, return TRUE if the
2880 s1 * s2 = {}
2881*/
2882
2883static unsigned int IntersectionIsNil (pge_SetDesc s1, pge_SetDesc s2);
2884
2885/*
2886 AddSet - adds a first symbol to a production.
2887*/
2888
2889static void AddSet (pge_SetDesc *to, NameKey_Name s);
2890
2891/*
2892 OrSet -
2893*/
2894
2895static void OrSet (pge_SetDesc *to, pge_SetDesc from);
2896
2897/*
2898 CalcFirstFactor -
2899*/
2900
2901static void CalcFirstFactor (pge_FactorDesc f, pge_ProductionDesc from, pge_SetDesc *to);
2902
2903/*
2904 CalcFirstTerm -
2905*/
2906
2907static void CalcFirstTerm (pge_TermDesc t, pge_ProductionDesc from, pge_SetDesc *to);
2908
2909/*
2910 CalcFirstExpression -
2911*/
2912
2913static void CalcFirstExpression (pge_ExpressionDesc e, pge_ProductionDesc from, pge_SetDesc *to);
2914
2915/*
2916 CalcFirstStatement -
2917*/
2918
2919static void CalcFirstStatement (pge_StatementDesc s, pge_ProductionDesc from, pge_SetDesc *to);
2920
2921/*
2922 CalcFirstProduction - calculates all of the first symbols for the grammer
2923*/
2924
2925static void CalcFirstProduction (pge_ProductionDesc p, pge_ProductionDesc from, pge_SetDesc *to);
2926static void WorkOutFollowFactor (pge_FactorDesc f, pge_SetDesc *followset, pge_SetDesc after);
2927
2928/*
2929 WorkOutFollowTerm -
2930*/
2931
2932static void WorkOutFollowTerm (pge_TermDesc t, pge_SetDesc *followset, pge_SetDesc after);
2933
2934/*
2935 WorkOutFollowExpression -
2936*/
2937
2938static void WorkOutFollowExpression (pge_ExpressionDesc e, pge_SetDesc *followset, pge_SetDesc after);
2939
2940/*
2941 CollectFollow - collects the follow set from, f, into, to.
2942*/
2943
2944static void CollectFollow (pge_SetDesc *to, pge_FollowDesc f);
2945
2946/*
2947 CalcFollowFactor -
2948*/
2949
2950static void CalcFollowFactor (pge_FactorDesc f, pge_SetDesc after);
2951
2952/*
2953 CalcFollowTerm -
2954*/
2955
2956static void CalcFollowTerm (pge_TermDesc t, pge_SetDesc after);
2957
2958/*
2959 CalcFollowExpression -
2960*/
2961
2962static void CalcFollowExpression (pge_ExpressionDesc e, pge_SetDesc after);
2963
2964/*
2965 CalcFollowStatement - given a bnf statement generate the follow set.
2966*/
2967
2968static void CalcFollowStatement (pge_StatementDesc s);
2969
2970/*
2971 CalcFollowProduction -
2972*/
2973
2974static void CalcFollowProduction (pge_ProductionDesc p);
2975
2976/*
2977 CalcEpsilonFactor -
2978*/
2979
2980static void CalcEpsilonFactor (pge_FactorDesc f);
2981
2982/*
2983 CalcEpsilonTerm -
2984*/
2985
2986static void CalcEpsilonTerm (pge_TermDesc t);
2987
2988/*
2989 CalcEpsilonExpression -
2990*/
2991
2992static void CalcEpsilonExpression (pge_ExpressionDesc e);
2993
2994/*
2995 CalcEpsilonStatement - given a bnf statement generate the follow set.
2996*/
2997
2998static void CalcEpsilonStatement (pge_StatementDesc s);
2999
3000/*
3001 CalcEpsilonProduction -
3002*/
3003
3004static void CalcEpsilonProduction (pge_ProductionDesc p);
3005
3006/*
3007 CalcReachEndFactor -
3008*/
3009
3010static pge_TraverseResult CalcReachEndFactor (pge_FactorDesc f);
3011
3012/*
3013 CalcReachEndTerm -
3014*/
3015
3016static pge_TraverseResult CalcReachEndTerm (pge_TermDesc t);
3017
3018/*
3019 CalcReachEndExpression -
3020*/
3021
3022static void CalcReachEndExpression (pge_ExpressionDesc e);
3023
3024/*
3025 CalcReachEndStatement -
3026*/
3027
3028static void CalcReachEndStatement (pge_StatementDesc s);
3029
3030/*
3031 CalcReachEndStatement -
3032*/
3033
3034static void stop (void);
3035
3036/*
3037 CalcReachEndProduction -
3038*/
3039
3040static void CalcReachEndProduction (pge_ProductionDesc p);
3041
3042/*
3043 EmptyFactor -
3044*/
3045
3046static unsigned int EmptyFactor (pge_FactorDesc f);
3047
3048/*
3049 EmptyTerm - returns TRUE if the term maybe empty.
3050*/
3051
3052static unsigned int EmptyTerm (pge_TermDesc t);
3053
3054/*
3055 EmptyExpression -
3056*/
3057
3058static unsigned int EmptyExpression (pge_ExpressionDesc e);
3059
3060/*
3061 EmptyStatement - returns TRUE if statement, s, is empty.
3062*/
3063
3064static unsigned int EmptyStatement (pge_StatementDesc s);
3065
3066/*
3067 EmptyProduction - returns if production, p, maybe empty.
3068*/
3069
3070static unsigned int EmptyProduction (pge_ProductionDesc p);
3071
3072/*
3073 EmitFDLNotice -
3074*/
3075
3076static void EmitFDLNotice (void);
3077
3078/*
3079 EmitRules - generates the BNF rules.
3080*/
3081
3082static void EmitRules (void);
3083
3084/*
3085 DescribeElement -
3086*/
3087
3088static void DescribeElement (unsigned int name);
3089
3090/*
3091 EmitInTestStop - construct a test for stop element, name.
3092*/
3093
3094static void EmitInTestStop (NameKey_Name name);
3095
3096/*
3097 DescribeStopElement -
3098*/
3099
3100static void DescribeStopElement (unsigned int name);
3101
3102/*
3103 EmitDescribeStop -
3104*/
3105
3106static void EmitDescribeStop (void);
3107
3108/*
3109 EmitDescribeError -
3110*/
3111
3112static void EmitDescribeError (void);
3113
3114/*
3115 EmitSetTypes - write out the set types used during error recovery
3116*/
3117
3118static void EmitSetTypes (void);
3119
3120/*
3121 EmitSupport - generates the support routines.
3122*/
3123
3124static void EmitSupport (void);
3125
3126/*
3127 DisposeSetDesc - dispose of the set list, s.
3128*/
3129
3130static void DisposeSetDesc (pge_SetDesc *s);
3131
3132/*
3133 OptionalFactor -
3134*/
3135
3136static unsigned int OptionalFactor (pge_FactorDesc f);
3137
3138/*
3139 OptionalTerm - returns TRUE if the term maybe empty.
3140*/
3141
3142static unsigned int OptionalTerm (pge_TermDesc t);
3143
3144/*
3145 OptionalExpression -
3146*/
3147
3148static unsigned int OptionalExpression (pge_ExpressionDesc e);
3149
3150/*
3151 OptionalStatement - returns FALSE if statement, s, does not have a optional ambiguity.
3152*/
3153
3154static unsigned int OptionalStatement (pge_StatementDesc s);
3155
3156/*
3157 OptionalProduction -
3158*/
3159
3160static unsigned int OptionalProduction (pge_ProductionDesc p);
3161
3162/*
3163 CheckFirstFollow -
3164*/
3165
3166static unsigned int CheckFirstFollow (pge_FactorDesc f, pge_FactorDesc after);
3167
3168/*
3169 ConstrainedEmptyFactor -
3170*/
3171
3172static unsigned int ConstrainedEmptyFactor (pge_FactorDesc f);
3173
3174/*
3175 ConstrainedEmptyTerm - returns TRUE if the term maybe empty.
3176*/
3177
3178static unsigned int ConstrainedEmptyTerm (pge_TermDesc t);
3179
3180/*
3181 ConstrainedEmptyExpression -
3182*/
3183
3184static unsigned int ConstrainedEmptyExpression (pge_ExpressionDesc e);
3185
3186/*
3187 ConstrainedEmptyStatement - returns FALSE if statement, s, does not have a optional ambiguity.
3188*/
3189
3190static unsigned int ConstrainedEmptyStatement (pge_StatementDesc s);
3191
3192/*
3193 ConstrainedEmptyProduction - returns TRUE if a problem exists with, p.
3194*/
3195
3196static unsigned int ConstrainedEmptyProduction (pge_ProductionDesc p);
3197
3198/*
3199 TestForLALR1 -
3200*/
3201
3202static void TestForLALR1 (pge_ProductionDesc p);
3203
3204/*
3205 DoEpsilon - runs the epsilon interrelated rules
3206*/
3207
3208static void DoEpsilon (pge_ProductionDesc p);
3209
3210/*
3211 CheckComplete - checks that production, p, is complete.
3212*/
3213
3214static void CheckComplete (pge_ProductionDesc p);
3215
3216/*
3217 PostProcessRules - backpatch the ident to rule definitions and emit comments and code.
3218*/
3219
3220static void PostProcessRules (void);
3221
3222/*
3223 DisplayHelp - display a summary help and then exit (0).
3224*/
3225
3226static void DisplayHelp (void);
3227
3228/*
3229 ParseArgs -
3230*/
3231
3232static void ParseArgs (void);
3233
3234/*
3235 Init - initialize the modules data structures
3236*/
3237
3238static void Init (void);
3239
3240
3241/*
3242 DescribeStop - issues a message explaining what tokens were expected
3243*/
3244
3245static DynamicStrings_String DescribeStop (pge_SetOfStop stopset)
3246{
3247 unsigned int n;
3248 DynamicStrings_String str;
3249 DynamicStrings_String message;
3250
3251 n = 0;
3252 message = DynamicStrings_InitString ((const char *) "", 0);
3253 if ((((1 << (bnflex_literaltok-bnflex_identtok)) & (stopset)) != 0))
3254 {
3255 message = DynamicStrings_ConCat (DynamicStrings_ConCatChar (message, ' '), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "literal", 7)));
3256 n += 1;
3257 }
3258 if ((((1 << (bnflex_identtok-bnflex_identtok)) & (stopset)) != 0))
3259 {
3260 message = DynamicStrings_ConCat (DynamicStrings_ConCatChar (message, ' '), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "identifier", 10)));
3261 n += 1;
3262 }
3263 if ((((1 << (bnflex_FNBtok-bnflex_identtok)) & (stopset)) != 0))
3264 {
3265 message = DynamicStrings_ConCat (DynamicStrings_ConCatChar (message, ' '), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "FNB", 3)));
3266 n += 1;
3267 }
3268 if ((((1 << (bnflex_BNFtok-bnflex_identtok)) & (stopset)) != 0))
3269 {
3270 message = DynamicStrings_ConCat (DynamicStrings_ConCatChar (message, ' '), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "BNF", 3)));
3271 n += 1;
3272 }
3273 if ((((1 << (bnflex_epsilontok-bnflex_identtok)) & (stopset)) != 0))
3274 {
3275 message = DynamicStrings_ConCat (DynamicStrings_ConCatChar (message, ' '), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "epsilon", 7)));
3276 n += 1;
3277 }
3278 if ((((1 << (bnflex_followtok-bnflex_identtok)) & (stopset)) != 0))
3279 {
3280 message = DynamicStrings_ConCat (DynamicStrings_ConCatChar (message, ' '), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "follow", 6)));
3281 n += 1;
3282 }
3283 if ((((1 << (bnflex_firsttok-bnflex_identtok)) & (stopset)) != 0))
3284 {
3285 message = DynamicStrings_ConCat (DynamicStrings_ConCatChar (message, ' '), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "first", 5)));
3286 n += 1;
3287 }
3288 if ((((1 << (bnflex_specialtok-bnflex_identtok)) & (stopset)) != 0))
3289 {
3290 message = DynamicStrings_ConCat (DynamicStrings_ConCatChar (message, ' '), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "special", 7)));
3291 n += 1;
3292 }
3293 if ((((1 << (bnflex_tokentok-bnflex_identtok)) & (stopset)) != 0))
3294 {
3295 message = DynamicStrings_ConCat (DynamicStrings_ConCatChar (message, ' '), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "token", 5)));
3296 n += 1;
3297 }
3298 if ((((1 << (bnflex_declarationtok-bnflex_identtok)) & (stopset)) != 0))
3299 {
3300 message = DynamicStrings_ConCat (DynamicStrings_ConCatChar (message, ' '), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "declaration", 11)));
3301 n += 1;
3302 }
3303 if ((((1 << (bnflex_endtok-bnflex_identtok)) & (stopset)) != 0))
3304 {
3305 message = DynamicStrings_ConCat (DynamicStrings_ConCatChar (message, ' '), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "end", 3)));
3306 n += 1;
3307 }
3308 if ((((1 << (bnflex_rulestok-bnflex_identtok)) & (stopset)) != 0))
3309 {
3310 message = DynamicStrings_ConCat (DynamicStrings_ConCatChar (message, ' '), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "rules", 5)));
3311 n += 1;
3312 }
3313 if ((((1 << (bnflex_begintok-bnflex_identtok)) & (stopset)) != 0))
3314 {
3315 message = DynamicStrings_ConCat (DynamicStrings_ConCatChar (message, ' '), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "begin", 5)));
3316 n += 1;
3317 }
3318 if ((((1 << (bnflex_moduletok-bnflex_identtok)) & (stopset)) != 0))
3319 {
3320 message = DynamicStrings_ConCat (DynamicStrings_ConCatChar (message, ' '), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "module", 6)));
3321 n += 1;
3322 }
3323 if ((((1 << (bnflex_dquotetok-bnflex_identtok)) & (stopset)) != 0))
3324 {
3325 message = DynamicStrings_ConCatChar (DynamicStrings_ConCatChar (DynamicStrings_ConCatChar (DynamicStrings_ConCatChar (DynamicStrings_ConCatChar (message, ' '), '`'), '"'), '\''), ',');
3326 n += 1;
3327 }
3328 if ((((1 << (bnflex_squotetok-bnflex_identtok)) & (stopset)) != 0))
3329 {
3330 message = DynamicStrings_ConCatChar (DynamicStrings_ConCatChar (DynamicStrings_ConCatChar (DynamicStrings_ConCatChar (DynamicStrings_ConCatChar (message, ' '), '"'), '\''), '"'), ',');
3331 n += 1;
3332 }
3333 if ((((1 << (bnflex_symfunctok-bnflex_identtok)) & (stopset)) != 0))
3334 {
3335 message = DynamicStrings_ConCat (DynamicStrings_ConCatChar (message, ' '), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "symfunc", 7)));
3336 n += 1;
3337 }
3338 if ((((1 << (bnflex_tfunctok-bnflex_identtok)) & (stopset)) != 0))
3339 {
3340 message = DynamicStrings_ConCat (DynamicStrings_ConCatChar (message, ' '), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "tokenfunc", 9)));
3341 n += 1;
3342 }
3343 if ((((1 << (bnflex_errortok-bnflex_identtok)) & (stopset)) != 0))
3344 {
3345 message = DynamicStrings_ConCat (DynamicStrings_ConCatChar (message, ' '), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "error", 5)));
3346 n += 1;
3347 }
3348 if ((((1 << (bnflex_gretok-bnflex_identtok)) & (stopset)) != 0))
3349 {
3350 message = DynamicStrings_ConCat (DynamicStrings_ConCatChar (message, ' '), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) ">", 1)));
3351 n += 1;
3352 }
3353 if ((((1 << (bnflex_lesstok-bnflex_identtok)) & (stopset)) != 0))
3354 {
3355 message = DynamicStrings_ConCat (DynamicStrings_ConCatChar (message, ' '), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "<", 1)));
3356 n += 1;
3357 }
3358 if ((((1 << (bnflex_rparatok-bnflex_identtok)) & (stopset)) != 0))
3359 {
3360 message = DynamicStrings_ConCat (DynamicStrings_ConCatChar (message, ' '), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) ")", 1)));
3361 n += 1;
3362 }
3363 if ((((1 << (bnflex_lparatok-bnflex_identtok)) & (stopset)) != 0))
3364 {
3365 message = DynamicStrings_ConCat (DynamicStrings_ConCatChar (message, ' '), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "(", 1)));
3366 n += 1;
3367 }
3368 if ((((1 << (bnflex_rcparatok-bnflex_identtok)) & (stopset)) != 0))
3369 {
3370 message = DynamicStrings_ConCat (DynamicStrings_ConCatChar (message, ' '), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "}", 1)));
3371 n += 1;
3372 }
3373 if ((((1 << (bnflex_lcparatok-bnflex_identtok)) & (stopset)) != 0))
3374 {
3375 message = DynamicStrings_ConCat (DynamicStrings_ConCatChar (message, ' '), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "{", 1)));
3376 n += 1;
3377 }
3378 if ((((1 << (bnflex_rsparatok-bnflex_identtok)) & (stopset)) != 0))
3379 {
3380 message = DynamicStrings_ConCat (DynamicStrings_ConCatChar (message, ' '), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "]", 1)));
3381 n += 1;
3382 }
3383 if ((((1 << (bnflex_lsparatok-bnflex_identtok)) & (stopset)) != 0))
3384 {
3385 message = DynamicStrings_ConCat (DynamicStrings_ConCatChar (message, ' '), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "[", 1)));
3386 n += 1;
3387 }
3388 if ((((1 << (bnflex_bartok-bnflex_identtok)) & (stopset)) != 0))
3389 {
3390 message = DynamicStrings_ConCat (DynamicStrings_ConCatChar (message, ' '), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "|", 1)));
3391 n += 1;
3392 }
3393 if ((((1 << (bnflex_rbecomestok-bnflex_identtok)) & (stopset)) != 0))
3394 {
3395 message = DynamicStrings_ConCat (DynamicStrings_ConCatChar (message, ' '), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "=:", 2)));
3396 n += 1;
3397 }
3398 if ((((1 << (bnflex_lbecomestok-bnflex_identtok)) & (stopset)) != 0))
3399 {
3400 message = DynamicStrings_ConCat (DynamicStrings_ConCatChar (message, ' '), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) ":=", 2)));
3401 n += 1;
3402 }
3403 if ((((1 << (bnflex_codetok-bnflex_identtok)) & (stopset)) != 0))
3404 {
3405 message = DynamicStrings_ConCat (DynamicStrings_ConCatChar (message, ' '), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "%", 1)));
3406 n += 1;
3407 }
3408 if ((((1 << (bnflex_eoftok-bnflex_identtok)) & (stopset)) != 0))
3409 {} /* empty. */
3410 /* eoftok has no token name (needed to generate error messages) */
3411 if (n == 0)
3412 {
3413 str = DynamicStrings_InitString ((const char *) " syntax error", 13);
3414 message = DynamicStrings_KillString (message);
3415 }
3416 else if (n == 1)
3417 {
3418 /* avoid dangling else. */
3419 str = DynamicStrings_ConCat (message, DynamicStrings_Mark (DynamicStrings_InitString ((const char *) " missing ", 9)));
3420 }
3421 else
3422 {
3423 /* avoid dangling else. */
3424 str = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) " expecting one of", 17), message);
3425 message = DynamicStrings_KillString (message);
3426 }
3427 return str;
3428 /* static analysis guarentees a RETURN statement will be used before here. */
3429 __builtin_unreachable ();
3430}
3431
3432
3433/*
3434 DescribeError - issues a message explaining what tokens were expected
3435*/
3436
3437static void DescribeError (void)
3438{
3439 DynamicStrings_String str;
3440
3441 str = DynamicStrings_InitString ((const char *) "", 0);
3442 switch (bnflex_GetCurrentTokenType ())
3443 {
3444 case bnflex_literaltok:
3445 str = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "syntax error, found literal", 27), DynamicStrings_Mark (str));
3446 break;
3447
3448 case bnflex_identtok:
3449 str = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "syntax error, found identifier", 30), DynamicStrings_Mark (str));
3450 break;
3451
3452 case bnflex_FNBtok:
3453 str = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "syntax error, found FNB", 23), DynamicStrings_Mark (str));
3454 break;
3455
3456 case bnflex_BNFtok:
3457 str = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "syntax error, found BNF", 23), DynamicStrings_Mark (str));
3458 break;
3459
3460 case bnflex_epsilontok:
3461 str = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "syntax error, found epsilon", 27), DynamicStrings_Mark (str));
3462 break;
3463
3464 case bnflex_followtok:
3465 str = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "syntax error, found follow", 26), DynamicStrings_Mark (str));
3466 break;
3467
3468 case bnflex_firsttok:
3469 str = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "syntax error, found first", 25), DynamicStrings_Mark (str));
3470 break;
3471
3472 case bnflex_specialtok:
3473 str = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "syntax error, found special", 27), DynamicStrings_Mark (str));
3474 break;
3475
3476 case bnflex_tokentok:
3477 str = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "syntax error, found token", 25), DynamicStrings_Mark (str));
3478 break;
3479
3480 case bnflex_declarationtok:
3481 str = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "syntax error, found declaration", 31), DynamicStrings_Mark (str));
3482 break;
3483
3484 case bnflex_endtok:
3485 str = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "syntax error, found end", 23), DynamicStrings_Mark (str));
3486 break;
3487
3488 case bnflex_rulestok:
3489 str = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "syntax error, found rules", 25), DynamicStrings_Mark (str));
3490 break;
3491
3492 case bnflex_begintok:
3493 str = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "syntax error, found begin", 25), DynamicStrings_Mark (str));
3494 break;
3495
3496 case bnflex_moduletok:
3497 str = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "syntax error, found module", 26), DynamicStrings_Mark (str));
3498 break;
3499
3500 case bnflex_dquotetok:
3501 str = DynamicStrings_ConCat (DynamicStrings_ConCatChar (DynamicStrings_ConCatChar (DynamicStrings_InitString ((const char *) "syntax error, found '", 21), '"'), '\''), DynamicStrings_Mark (str));
3502 break;
3503
3504 case bnflex_squotetok:
3505 str = DynamicStrings_ConCat (DynamicStrings_ConCatChar (DynamicStrings_ConCatChar (DynamicStrings_InitString ((const char *) "syntax error, found \"", 21), '\''), '"'), DynamicStrings_Mark (str));
3506 break;
3507
3508 case bnflex_symfunctok:
3509 str = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "syntax error, found symfunc", 27), DynamicStrings_Mark (str));
3510 break;
3511
3512 case bnflex_tfunctok:
3513 str = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "syntax error, found tokenfunc", 29), DynamicStrings_Mark (str));
3514 break;
3515
3516 case bnflex_errortok:
3517 str = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "syntax error, found error", 25), DynamicStrings_Mark (str));
3518 break;
3519
3520 case bnflex_gretok:
3521 str = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "syntax error, found >", 21), DynamicStrings_Mark (str));
3522 break;
3523
3524 case bnflex_lesstok:
3525 str = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "syntax error, found <", 21), DynamicStrings_Mark (str));
3526 break;
3527
3528 case bnflex_rparatok:
3529 str = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "syntax error, found )", 21), DynamicStrings_Mark (str));
3530 break;
3531
3532 case bnflex_lparatok:
3533 str = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "syntax error, found (", 21), DynamicStrings_Mark (str));
3534 break;
3535
3536 case bnflex_rcparatok:
3537 str = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "syntax error, found }", 21), DynamicStrings_Mark (str));
3538 break;
3539
3540 case bnflex_lcparatok:
3541 str = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "syntax error, found {", 21), DynamicStrings_Mark (str));
3542 break;
3543
3544 case bnflex_rsparatok:
3545 str = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "syntax error, found ]", 21), DynamicStrings_Mark (str));
3546 break;
3547
3548 case bnflex_lsparatok:
3549 str = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "syntax error, found [", 21), DynamicStrings_Mark (str));
3550 break;
3551
3552 case bnflex_bartok:
3553 str = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "syntax error, found |", 21), DynamicStrings_Mark (str));
3554 break;
3555
3556 case bnflex_rbecomestok:
3557 str = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "syntax error, found =:", 22), DynamicStrings_Mark (str));
3558 break;
3559
3560 case bnflex_lbecomestok:
3561 str = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "syntax error, found :=", 22), DynamicStrings_Mark (str));
3562 break;
3563
3564 case bnflex_codetok:
3565 str = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "syntax error, found %", 21), DynamicStrings_Mark (str));
3566 break;
3567
3568 case bnflex_eoftok:
3569 str = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "syntax error, found ", 20), DynamicStrings_Mark (str));
3570 break;
3571
3572
3573 default:
3574 break;
3575 }
3576 PushBackInput_WarnString (str);
3577}
3578
3579
3580/*
3581 AddEntry - adds an entry into, t, containing [def:value].
3582*/
3583
3584static void AddEntry (SymbolKey_SymbolTree *t, NameKey_Name def, NameKey_Name value)
3585{
3586 if (SymbolKey_ContainsSymKey ((*t), def))
3587 {
3588 WarnError1 ((const char *) "already seen a definition for token '%s'", 40, def);
3589 }
3590 else
3591 {
3592 SymbolKey_PutSymKey ((*t), def, value);
3593 }
3594}
3595
3596
3597/*
3598 Format1 - converts string, src, into, dest, together with encapsulated
3599 entity, n. It only formats the first %s or %d with n.
3600*/
3601
3602static void Format1 (const char *src_, unsigned int _src_high, unsigned int n, char *dest, unsigned int _dest_high)
3603{
3604 typedef struct Format1__T12_a Format1__T12;
3605
3606 struct Format1__T12_a { char array[MaxString+1]; };
3607 unsigned int HighSrc;
3608 unsigned int HighDest;
3609 unsigned int i;
3610 unsigned int j;
3611 Format1__T12 str;
3612 char src[_src_high+1];
3613
3614 /* make a local copy of each unbounded array. */
3615 memcpy (src, src_, _src_high+1);
3616
3617 HighSrc = StrLib_StrLen ((const char *) src, _src_high);
3618 HighDest = _dest_high;
3619 i = 0;
3620 j = 0;
3621 while ((((i < HighSrc) && (src[i] != ASCII_nul)) && (j < HighDest)) && (src[i] != '%'))
3622 {
3623 dest[j] = src[i];
3624 i += 1;
3625 j += 1;
3626 }
3627 if ((((i+1) < HighSrc) && (src[i] == '%')) && (j < HighDest))
3628 {
3629 /* avoid gcc warning by using compound statement even if not strictly necessary. */
3630 if (src[i+1] == 's')
3631 {
3632 dest[j] = ASCII_nul;
3633 NameKey_GetKey (n, (char *) &str.array[0], MaxString);
3634 StrLib_StrConCat ((const char *) dest, _dest_high, (const char *) &str.array[0], MaxString, (char *) dest, _dest_high);
3635 j = StrLib_StrLen ((const char *) dest, _dest_high);
3636 i += 2;
3637 }
3638 else if (src[i+1] == 'd')
3639 {
3640 /* avoid dangling else. */
3641 dest[j] = ASCII_nul;
3642 NumberIO_CardToStr (n, 0, (char *) &str.array[0], MaxString);
3643 StrLib_StrConCat ((const char *) dest, _dest_high, (const char *) &str.array[0], MaxString, (char *) dest, _dest_high);
3644 j = StrLib_StrLen ((const char *) dest, _dest_high);
3645 i += 2;
3646 }
3647 else
3648 {
3649 /* avoid dangling else. */
3650 dest[j] = src[i];
3651 i += 1;
3652 j += 1;
3653 }
3654 }
3655 /* and finish off copying src into dest */
3656 while (((i < HighSrc) && (src[i] != ASCII_nul)) && (j < HighDest))
3657 {
3658 dest[j] = src[i];
3659 i += 1;
3660 j += 1;
3661 }
3662 if (j < HighDest)
3663 {
3664 dest[j] = ASCII_nul;
3665 }
3666}
3667
3668
3669/*
3670 WarnError1 -
3671*/
3672
3673static void WarnError1 (const char *a_, unsigned int _a_high, unsigned int n)
3674{
3675 typedef struct WarnError1__T13_a WarnError1__T13;
3676
3677 struct WarnError1__T13_a { char array[MaxString+1]; };
3678 WarnError1__T13 line;
3679 char a[_a_high+1];
3680
3681 /* make a local copy of each unbounded array. */
3682 memcpy (a, a_, _a_high+1);
3683
3684 Format1 ((const char *) a, _a_high, n, (char *) &line.array[0], MaxString);
3685 PushBackInput_WarnError ((const char *) &line.array[0], MaxString);
3686}
3687
3688
3689/*
3690 PrettyFollow -
3691*/
3692
3693static void PrettyFollow (const char *start_, unsigned int _start_high, const char *end_, unsigned int _end_high, pge_FollowDesc f)
3694{
3695 char start[_start_high+1];
3696 char end[_end_high+1];
3697
3698 /* make a local copy of each unbounded array. */
3699 memcpy (start, start_, _start_high+1);
3700 memcpy (end, end_, _end_high+1);
3701
3702 if (Debugging)
3703 {
3704 Output_WriteString ((const char *) start, _start_high);
3705 if (f != NULL)
3706 {
3707 if (f->calcfollow)
3708 {
3709 Output_WriteString ((const char *) "followset defined as:", 21);
3710 EmitSet (f->follow, static_cast<unsigned int> (0), static_cast<unsigned int> (0));
3711 }
3712 switch (f->reachend)
3713 {
3714 case pge_true:
3715 Output_WriteString ((const char *) " [E]", 4);
3716 break;
3717
3718 case pge_false:
3719 Output_WriteString ((const char *) " [C]", 4);
3720 break;
3721
3722 case pge_unknown:
3723 Output_WriteString ((const char *) " [U]", 4);
3724 break;
3725
3726
3727 default:
3728 break;
3729 }
3730 switch (f->epsilon)
3731 {
3732 case pge_true:
3733 Output_WriteString ((const char *) " [e]", 4);
3734 break;
3735
3736 case pge_false:
3737 break;
3738
3739 case pge_unknown:
3740 Output_WriteString ((const char *) " [u]", 4);
3741 break;
3742
3743
3744 default:
3745 break;
3746 }
3747 }
3748 Output_WriteString ((const char *) end, _end_high);
3749 }
3750}
3751
3752
3753/*
3754 NewFollow - creates a new follow descriptor and returns the data structure.
3755*/
3756
3757static pge_FollowDesc NewFollow (void)
3758{
3759 pge_FollowDesc f;
3760
3761 Storage_ALLOCATE ((void **) &f, sizeof (pge__T6));
3762 f->follow = NULL;
3763 f->reachend = pge_unknown;
3764 f->epsilon = pge_unknown;
3765 return f;
3766 /* static analysis guarentees a RETURN statement will be used before here. */
3767 __builtin_unreachable ();
3768}
3769
3770
3771/*
3772 AssignEpsilon - assigns the epsilon value and sets the epsilon to value,
3773 providing condition is TRUE.
3774*/
3775
3776static void AssignEpsilon (unsigned int condition, pge_FollowDesc f, pge_TraverseResult value)
3777{
3778 if ((condition && (value != pge_unknown)) && (f->epsilon == pge_unknown))
3779 {
3780 f->epsilon = value;
3781 Finished = FALSE;
3782 }
3783}
3784
3785
3786/*
3787 GetEpsilon - returns the value of epsilon
3788*/
3789
3790static pge_TraverseResult GetEpsilon (pge_FollowDesc f)
3791{
3792 if (f == NULL)
3793 {
3794 Debug_Halt ((const char *) "why is the follow info NIL?", 27, 596, (const char *) "m2/gm2-auto/pge.mod", 19);
3795 }
3796 else
3797 {
3798 return f->epsilon;
3799 }
3800 ReturnException ("m2/gm2-auto/pge.mod", 1, 7);
3801 __builtin_unreachable ();
3802}
3803
3804
3805/*
3806 AssignReachEnd - assigns the reachend value providing that, condition, is TRUE.
3807*/
3808
3809static void AssignReachEnd (unsigned int condition, pge_FollowDesc f, pge_TraverseResult value)
3810{
3811 if (condition)
3812 {
3813 if ((f->reachend == pge_unknown) && (value != pge_unknown))
3814 {
3815 f->reachend = value;
3816 Finished = FALSE;
3817 }
3818 }
3819}
3820
3821
3822/*
3823 GetReachEnd - returns the value of reachend
3824*/
3825
3826static pge_TraverseResult GetReachEnd (pge_FollowDesc f)
3827{
3828 if (f == NULL)
3829 {
3830 Debug_Halt ((const char *) "why is the follow info NIL?", 27, 630, (const char *) "m2/gm2-auto/pge.mod", 19);
3831 }
3832 else
3833 {
3834 return f->reachend;
3835 }
3836 ReturnException ("m2/gm2-auto/pge.mod", 1, 7);
3837 __builtin_unreachable ();
3838}
3839
3840
3841/*
3842 AssignFollow - assigns the follow set and sets the calcfollow to TRUE.
3843*/
3844
3845static void AssignFollow (pge_FollowDesc f, pge_SetDesc s)
3846{
3847 if (f->calcfollow)
3848 {
3849 Debug_Halt ((const char *) "why are we reassigning this follow set?", 39, 646, (const char *) "m2/gm2-auto/pge.mod", 19);
3850 }
3851 f->follow = s;
3852 f->calcfollow = TRUE;
3853}
3854
3855
3856/*
3857 GetFollow - returns the follow set.
3858*/
3859
3860static pge_SetDesc GetFollow (pge_FollowDesc f)
3861{
3862 if (f == NULL)
3863 {
3864 Debug_Halt ((const char *) "why is the follow info NIL?", 27, 662, (const char *) "m2/gm2-auto/pge.mod", 19);
3865 }
3866 else
3867 {
3868 if (f->calcfollow)
3869 {
3870 return f->follow;
3871 }
3872 else
3873 {
3874 Debug_Halt ((const char *) "not calculated the follow set yet..", 35, 669, (const char *) "m2/gm2-auto/pge.mod", 19);
3875 }
3876 }
3877 ReturnException ("m2/gm2-auto/pge.mod", 1, 7);
3878 __builtin_unreachable ();
3879}
3880
3881
3882/*
3883 NewProduction - creates a new production and returns the data structure.
3884*/
3885
3886static pge_ProductionDesc NewProduction (void)
3887{
3888 pge_ProductionDesc p;
3889
3890 Storage_ALLOCATE ((void **) &p, sizeof (pge__T2));
3891 if (TailProduction != NULL)
3892 {
3893 TailProduction->next = p;
3894 }
3895 TailProduction = p;
3896 if (HeadProduction == NULL)
3897 {
3898 HeadProduction = p;
3899 }
3900 p->next = NULL;
3901 p->statement = NULL;
3902 p->first = NULL;
3903 p->firstsolved = FALSE;
3904 p->followinfo = NewFollow ();
3905 p->line = PushBackInput_GetCurrentLine ();
3906 p->description = NameKey_NulName;
3907 return p;
3908 /* static analysis guarentees a RETURN statement will be used before here. */
3909 __builtin_unreachable ();
3910}
3911
3912
3913/*
3914 NewFactor -
3915*/
3916
3917static pge_FactorDesc NewFactor (void)
3918{
3919 pge_FactorDesc f;
3920
3921 Storage_ALLOCATE ((void **) &f, sizeof (pge__T5));
3922 f->next = NULL;
3923 f->followinfo = NewFollow ();
3924 f->line = PushBackInput_GetCurrentLine ();
3925 return f;
3926 /* static analysis guarentees a RETURN statement will be used before here. */
3927 __builtin_unreachable ();
3928}
3929
3930
3931/*
3932 NewTerm - returns a new term.
3933*/
3934
3935static pge_TermDesc NewTerm (void)
3936{
3937 pge_TermDesc t;
3938
3939 Storage_ALLOCATE ((void **) &t, sizeof (pge_termdesc));
3940 t->factor = NULL;
3941 t->followinfo = NewFollow ();
3942 t->next = NULL;
3943 t->line = PushBackInput_GetCurrentLine ();
3944 return t;
3945 /* static analysis guarentees a RETURN statement will be used before here. */
3946 __builtin_unreachable ();
3947}
3948
3949
3950/*
3951 NewExpression - returns a new expression.
3952*/
3953
3954static pge_ExpressionDesc NewExpression (void)
3955{
3956 pge_ExpressionDesc e;
3957
3958 Storage_ALLOCATE ((void **) &e, sizeof (pge__T4));
3959 e->term = NULL;
3960 e->followinfo = NewFollow ();
3961 e->line = PushBackInput_GetCurrentLine ();
3962 return e;
3963 /* static analysis guarentees a RETURN statement will be used before here. */
3964 __builtin_unreachable ();
3965}
3966
3967
3968/*
3969 NewStatement - returns a new statement.
3970*/
3971
3972static pge_StatementDesc NewStatement (void)
3973{
3974 pge_StatementDesc s;
3975
3976 Storage_ALLOCATE ((void **) &s, sizeof (pge__T3));
3977 s->ident = NULL;
3978 s->expr = NULL;
3979 s->followinfo = NewFollow ();
3980 s->line = PushBackInput_GetCurrentLine ();
3981 return s;
3982 /* static analysis guarentees a RETURN statement will be used before here. */
3983 __builtin_unreachable ();
3984}
3985
3986
3987/*
3988 NewSetDesc - creates a new set description and returns the data structure.
3989*/
3990
3991static pge_SetDesc NewSetDesc (void)
3992{
3993 pge_SetDesc s;
3994
3995 Storage_ALLOCATE ((void **) &s, sizeof (pge__T7));
3996 s->next = NULL;
3997 return s;
3998 /* static analysis guarentees a RETURN statement will be used before here. */
3999 __builtin_unreachable ();
4000}
4001
4002
4003/*
4004 NewCodeDesc - creates a new code descriptor and initializes all fields to zero.
4005*/
4006
4007static pge_CodeDesc NewCodeDesc (void)
4008{
4009 pge_CodeDesc c;
4010
4011 Storage_ALLOCATE ((void **) &c, sizeof (pge__T8));
4012 c->code = NULL;
4013 c->indent = 0;
4014 c->line = PushBackInput_GetCurrentLine ();
4015 return c;
4016 /* static analysis guarentees a RETURN statement will be used before here. */
4017 __builtin_unreachable ();
4018}
4019
4020
4021/*
4022 CodeFragmentPrologue - consumes code text up to a "%" after a newline.
4023*/
4024
4025static void CodeFragmentPrologue (void)
4026{
4027 LinePrologue = PushBackInput_GetCurrentLine ();
4028 GetCodeFragment (&CodePrologue);
4029}
4030
4031
4032/*
4033 CodeFragmentEpilogue - consumes code text up to a "%" after a newline.
4034*/
4035
4036static void CodeFragmentEpilogue (void)
4037{
4038 LineEpilogue = PushBackInput_GetCurrentLine ();
4039 GetCodeFragment (&CodeEpilogue);
4040}
4041
4042
4043/*
4044 CodeFragmentDeclaration - consumes code text up to a "%" after a newline.
4045*/
4046
4047static void CodeFragmentDeclaration (void)
4048{
4049 LineDeclaration = PushBackInput_GetCurrentLine ();
4050 GetCodeFragment (&CodeDeclaration);
4051}
4052
4053
4054/*
4055 GetCodeFragment - collects the code fragment up until ^ %
4056*/
4057
4058static void GetCodeFragment (pge_CodeHunk *h)
4059{
4060 unsigned int i;
4061 char ch;
4062
4063 (*h) = NULL;
4064 i = 0;
4065 while (((bnflex_PutChar (bnflex_GetChar ())) != '%') && ((bnflex_PutChar (bnflex_GetChar ())) != ASCII_nul))
4066 {
4067 do {
4068 while (((bnflex_PutChar (bnflex_GetChar ())) != ASCII_nul) && ((bnflex_PutChar (bnflex_GetChar ())) != ASCII_lf))
4069 {
4070 (*h) = Add (h, bnflex_GetChar (), &i);
4071 }
4072 if ((bnflex_PutChar (bnflex_GetChar ())) == ASCII_lf)
4073 {
4074 /* consume line feed */
4075 (*h) = Add (h, bnflex_GetChar (), &i);
4076 ch = bnflex_PutChar (ASCII_lf);
4077 }
4078 else if ((bnflex_PutChar (bnflex_GetChar ())) == ASCII_nul)
4079 {
4080 /* avoid dangling else. */
4081 ch = bnflex_PutChar (ASCII_nul);
4082 ch = bnflex_PutChar (ASCII_lf);
4083 }
4084 else
4085 {
4086 /* avoid dangling else. */
4087 ch = bnflex_PutChar (bnflex_PutChar (bnflex_GetChar ()));
4088 }
4089 } while (! ((bnflex_GetChar ()) == ASCII_lf));
4090 }
4091 if ((bnflex_PutChar (bnflex_GetChar ())) == '%')
4092 {
4093 (*h) = Add (h, ASCII_nul, &i);
4094 ch = bnflex_PutChar (' '); /* to give the following token % a delimiter infront of it */
4095 bnflex_AdvanceToken (); /* to give the following token % a delimiter infront of it */
4096 }
4097 else
4098 {
4099 PushBackInput_WarnError ((const char *) "expecting % to terminate code fragment, found end of file", 57);
4100 }
4101}
4102
4103
4104/*
4105 WriteCodeHunkList - writes the CodeHunk list in the correct order.
4106*/
4107
4108static void WriteCodeHunkList (pge_CodeHunk l)
4109{
4110 if (l != NULL)
4111 {
4112 OnLineStart = FALSE;
4113 /* recursion */
4114 WriteCodeHunkList (l->next);
4115 Output_WriteString ((const char *) &l->codetext.array[0], MaxCodeHunkLength);
4116 }
4117}
4118
4119
4120/*
4121 WriteIndent - writes, n, spaces.
4122*/
4123
4124static void WriteIndent (unsigned int n)
4125{
4126 while (n > 0)
4127 {
4128 Output_Write (' ');
4129 n -= 1;
4130 }
4131 OnLineStart = FALSE;
4132}
4133
4134
4135/*
4136 CheckWrite -
4137*/
4138
4139static void CheckWrite (char ch, unsigned int *curpos, unsigned int left, unsigned int *seentext)
4140{
4141 if (ch == ASCII_lf)
4142 {
4143 NewLine (left);
4144 (*curpos) = 0;
4145 (*seentext) = FALSE;
4146 }
4147 else
4148 {
4149 Output_Write (ch);
4150 (*curpos) += 1;
4151 }
4152}
4153
4154
4155/*
4156 WriteStringIndent - writes a string but it will try and remove upto indent spaces
4157 if they exist.
4158*/
4159
4160static void WriteStringIndent (const char *a_, unsigned int _a_high, unsigned int indent, unsigned int *curpos, unsigned int left, unsigned int *seentext)
4161{
4162 unsigned int l;
4163 unsigned int i;
4164 char a[_a_high+1];
4165
4166 /* make a local copy of each unbounded array. */
4167 memcpy (a, a_, _a_high+1);
4168
4169 i = 0;
4170 l = StrLib_StrLen ((const char *) a, _a_high);
4171 while (i < l)
4172 {
4173 if ((*seentext))
4174 {
4175 CheckWrite (a[i], curpos, left, seentext);
4176 }
4177 else
4178 {
4179 if (a[i] == ' ')
4180 {
4181 /* ignore space for now */
4182 (*curpos) += 1;
4183 }
4184 else
4185 {
4186 if ((*curpos) >= indent)
4187 {
4188 WriteIndent ((*curpos)-indent);
4189 }
4190 (*seentext) = TRUE;
4191 CheckWrite (a[i], curpos, left, seentext);
4192 }
4193 }
4194 i += 1;
4195 }
4196}
4197
4198
4199/*
4200 WriteCodeHunkListIndent - writes the CodeHunk list in the correct order
4201 but it removes up to indent spaces if they exist.
4202*/
4203
4204static void WriteCodeHunkListIndent (pge_CodeHunk l, unsigned int indent, unsigned int *curpos, unsigned int left, unsigned int *seentext)
4205{
4206 if (l != NULL)
4207 {
4208 /* recursion */
4209 WriteCodeHunkListIndent (l->next, indent, curpos, left, seentext);
4210 WriteStringIndent ((const char *) &l->codetext.array[0], MaxCodeHunkLength, indent, curpos, left, seentext);
4211 }
4212}
4213
4214
4215/*
4216 Add - adds a character to a code hunk and creates another code hunk if necessary.
4217*/
4218
4219static pge_CodeHunk Add (pge_CodeHunk *p, char ch, unsigned int *i)
4220{
4221 pge_CodeHunk q;
4222
4223 if (((*p) == NULL) || ((*i) > MaxCodeHunkLength))
4224 {
4225 Storage_ALLOCATE ((void **) &q, sizeof (pge__T9));
4226 q->next = (*p);
4227 q->codetext.array[0] = ch;
4228 (*i) = 1;
4229 return q;
4230 }
4231 else
4232 {
4233 (*p)->codetext.array[(*i)] = ch;
4234 (*i) += 1;
4235 return (*p);
4236 }
4237 /* static analysis guarentees a RETURN statement will be used before here. */
4238 __builtin_unreachable ();
4239}
4240
4241
4242/*
4243 ConsHunk - combine two possible code hunks.
4244*/
4245
4246static void ConsHunk (pge_CodeHunk *p, pge_CodeHunk q)
4247{
4248 pge_CodeHunk r;
4249
4250 if ((*p) != NULL)
4251 {
4252 r = q;
4253 while (r->next != NULL)
4254 {
4255 r = r->next;
4256 }
4257 r->next = (*p);
4258 }
4259 (*p) = q;
4260}
4261
4262
4263/*
4264 GetName - returns the next symbol which is checked for a legal name.
4265*/
4266
4267static NameKey_Name GetName (void)
4268{
4269 NameKey_Name name;
4270
4271 if (bnflex_IsReserved (bnflex_GetCurrentToken ()))
4272 {
4273 PushBackInput_WarnError ((const char *) "expecting a name and found a reserved word", 42);
4274 bnflex_AdvanceToken (); /* move on to another token */
4275 return NameKey_NulName; /* move on to another token */
4276 }
4277 else
4278 {
4279 name = bnflex_GetCurrentToken ();
4280 bnflex_AdvanceToken ();
4281 return name;
4282 }
4283 /* static analysis guarentees a RETURN statement will be used before here. */
4284 __builtin_unreachable ();
4285}
4286
4287
4288/*
4289 SyntaxError - after a syntax error we skip all tokens up until we reach
4290 a stop symbol.
4291*/
4292
4293static void SyntaxError (pge_SetOfStop stop)
4294{
4295 DescribeError ();
4296 if (Debugging)
4297 {
4298 StrIO_WriteLn ();
4299 StrIO_WriteString ((const char *) "skipping token *** ", 19);
4300 }
4301 while (! ((((1 << (bnflex_GetCurrentTokenType ()-bnflex_identtok)) & (stop)) != 0)))
4302 {
4303 bnflex_AdvanceToken ();
4304 }
4305 if (Debugging)
4306 {
4307 StrIO_WriteString ((const char *) " ***", 4);
4308 StrIO_WriteLn ();
4309 }
4310 WasNoError = FALSE;
4311}
4312
4313
4314/*
4315 SyntaxCheck -
4316*/
4317
4318static void SyntaxCheck (pge_SetOfStop stop)
4319{
4320 if (! ((((1 << (bnflex_GetCurrentTokenType ()-bnflex_identtok)) & (stop)) != 0)))
4321 {
4322 SyntaxError (stop);
4323 }
4324}
4325
4326
4327/*
4328 Expect -
4329*/
4330
4331static void Expect (bnflex_TokenType t, pge_SetOfStop stop)
4332{
4333 if ((bnflex_GetCurrentTokenType ()) == t)
4334 {
4335 bnflex_AdvanceToken ();
4336 }
4337 else
4338 {
4339 SyntaxError (stop);
4340 }
4341 SyntaxCheck (stop);
4342}
4343
4344
4345/*
4346 Ident - error checking varient of Ident
4347*/
4348
4349static void Ident (pge_SetOfStop stop)
4350{
4351 if ((bnflex_GetCurrentTokenType ()) == bnflex_identtok)
4352 {
4353 Storage_ALLOCATE ((void **) &CurrentIdent, sizeof (pge__T1));
4354 CurrentIdent->definition = NULL;
4355 CurrentIdent->name = GetName ();
4356 CurrentIdent->line = PushBackInput_GetCurrentLine ();
4357 }
4358}
4359
4360
4361/*
4362 Modula2Code - error checking varient of Modula2Code
4363*/
4364
4365static void Modula2Code (pge_SetOfStop stop)
4366{
4367 pge_CodeHunk p;
4368 unsigned int i;
4369 unsigned int quote;
4370 unsigned int line;
4371 unsigned int position;
4372
4373 line = PushBackInput_GetCurrentLine ();
4374 bnflex_PushBackToken (bnflex_GetCurrentToken ());
4375 position = PushBackInput_GetColumnPosition ();
4376 p = NULL;
4377 bnflex_SkipWhite ();
4378 while (((bnflex_PutChar (bnflex_GetChar ())) != '%') && ((bnflex_PutChar (bnflex_GetChar ())) != ASCII_nul))
4379 {
4380 if ((bnflex_PutChar (bnflex_GetChar ())) == '"')
4381 {
4382 /* avoid dangling else. */
4383 do {
4384 p = Add (&p, bnflex_GetChar (), &i);
4385 } while (! (((bnflex_PutChar (bnflex_GetChar ())) == '"') || ((bnflex_PutChar (bnflex_GetChar ())) == ASCII_nul)));
4386 p = Add (&p, '"', &i);
4387 if (((bnflex_PutChar (bnflex_GetChar ())) == '"') && ((bnflex_GetChar ()) == '"'))
4388 {} /* empty. */
4389 }
4390 else if ((bnflex_PutChar (bnflex_GetChar ())) == '\'')
4391 {
4392 /* avoid dangling else. */
4393 do {
4394 p = Add (&p, bnflex_GetChar (), &i);
4395 } while (! (((bnflex_PutChar (bnflex_GetChar ())) == '\'') || ((bnflex_PutChar (bnflex_GetChar ())) == ASCII_nul)));
4396 p = Add (&p, '\'', &i);
4397 if (((bnflex_PutChar (bnflex_GetChar ())) == '\'') && ((bnflex_GetChar ()) == '\''))
4398 {} /* empty. */
4399 }
4400 else if (((bnflex_PutChar (bnflex_GetChar ())) == '\\') && ((bnflex_GetChar ()) == '\\'))
4401 {
4402 /* avoid dangling else. */
4403 p = Add (&p, bnflex_GetChar (), &i);
4404 }
4405 else if ((bnflex_PutChar (bnflex_GetChar ())) != '%')
4406 {
4407 /* avoid dangling else. */
4408 p = Add (&p, bnflex_GetChar (), &i);
4409 }
4410 }
4411 p = Add (&p, ASCII_nul, &i);
4412 CurrentFactor->type = pge_m2;
4413 CurrentFactor->code = NewCodeDesc ();
4414 CurrentFactor->code->code = p;
4415 CurrentFactor->code->indent = position;
4416 if ((bnflex_PutChar (' ')) == ' ')
4417 {} /* empty. */
4418 bnflex_AdvanceToken (); /* read the next token ready for the parser */
4419 if (! WasNoError) /* read the next token ready for the parser */
4420 {
4421 WarnError1 ((const char *) "error probably occurred before the start of inline code on line %d", 66, line);
4422 }
4423}
4424
4425
4426/*
4427 StartModName := % ModuleName := GetName() ; ignore begintok CodeFragmentPrologue % =:
4428*/
4429
4430static void StartModName (pge_SetOfStop stop)
4431{
4432 ModuleName = GetName ();
4433 CodeFragmentPrologue ();
4434}
4435
4436
4437/*
4438 EndModName :=
4439*/
4440
4441static void EndModName (pge_SetOfStop stop)
4442{
4443 if (ModuleName != (GetName ()))
4444 {
4445 PushBackInput_WarnError ((const char *) "expecting same module name at end as beginning", 46);
4446 }
4447 /* ignore endtok as it consumes the token afterwards */
4448 CodeFragmentEpilogue ();
4449}
4450
4451
4452/*
4453 DoDeclaration := % CodeFragmentDeclaration % =:
4454*/
4455
4456static void DoDeclaration (pge_SetOfStop stop)
4457{
4458 if (ModuleName != (GetName ()))
4459 {
4460 PushBackInput_WarnError ((const char *) "expecting same module name in declaration as in the beginning", 61);
4461 }
4462 /* ignore begintok as it consumes the token afterwards */
4463 CodeFragmentDeclaration ();
4464}
4465
4466
4467/*
4468 CollectLiteral :=
4469 % LastLiteral := GetCurrentToken() ;
4470 AdvanceToken ; %
4471
4472
4473 first symbols:literaltok
4474
4475 cannot reachend
4476*/
4477
4478static void CollectLiteral (pge_SetOfStop stopset)
4479{
4480 LastLiteral = bnflex_GetCurrentToken (); /* */
4481 bnflex_AdvanceToken ();
4482}
4483
4484
4485/*
4486 CollectTok :=
4487 % CurrentSetDesc := NewSetDesc() ;
4488 WITH CurrentSetDesc^ DO
4489 type := tokel ;
4490 string := GetCurrentToken() ;
4491 END ;
4492 IF NOT ContainsSymKey(Values, GetCurrentToken())
4493 THEN
4494 AddEntry(Values, GetCurrentToken(), LargestValue) ;
4495 AddEntry(ReverseValues, Name(LargestValue), GetCurrentToken()) ;
4496 AddEntry(Aliases, GetCurrentToken(), GetCurrentToken()) ;
4497 AddEntry(ReverseAliases, GetCurrentToken(), GetCurrentToken()) ;
4498 INC(LargestValue)
4499 END ;
4500 AdvanceToken() ; %
4501
4502
4503 first symbols:identtok
4504
4505 cannot reachend
4506*/
4507
4508static void CollectTok (pge_SetOfStop stopset)
4509{
4510 CurrentSetDesc = NewSetDesc (); /* */
4511 CurrentSetDesc->type = pge_tokel;
4512 CurrentSetDesc->string = bnflex_GetCurrentToken ();
4513 if (! (SymbolKey_ContainsSymKey (Values, bnflex_GetCurrentToken ())))
4514 {
4515 AddEntry (&Values, bnflex_GetCurrentToken (), LargestValue);
4516 AddEntry (&ReverseValues, (NameKey_Name) (LargestValue), bnflex_GetCurrentToken ());
4517 AddEntry (&Aliases, bnflex_GetCurrentToken (), bnflex_GetCurrentToken ());
4518 AddEntry (&ReverseAliases, bnflex_GetCurrentToken (), bnflex_GetCurrentToken ());
4519 LargestValue += 1;
4520 }
4521 bnflex_AdvanceToken ();
4522}
4523
4524
4525/*
4526 DefineToken :=
4527 % AddEntry(Aliases, LastLiteral, GetCurrentToken()) ;
4528 AddEntry(ReverseAliases, GetCurrentToken(), LastLiteral) ;
4529 AddEntry(Values, GetCurrentToken(), LargestValue) ;
4530 AddEntry(ReverseValues, Name(LargestValue), GetCurrentToken()) ;
4531 INC(LargestValue) ;
4532 AdvanceToken ; %
4533
4534
4535 first symbols:identtok
4536
4537 cannot reachend
4538*/
4539
4540static void DefineToken (pge_SetOfStop stopset)
4541{
4542 AddEntry (&Aliases, LastLiteral, bnflex_GetCurrentToken ()); /* */
4543 AddEntry (&ReverseAliases, bnflex_GetCurrentToken (), LastLiteral);
4544 AddEntry (&Values, bnflex_GetCurrentToken (), LargestValue);
4545 AddEntry (&ReverseValues, (NameKey_Name) (LargestValue), bnflex_GetCurrentToken ());
4546 LargestValue += 1;
4547 bnflex_AdvanceToken ();
4548}
4549
4550
4551/*
4552 Rules := '%' 'rules' { Defs } ExtBNF
4553
4554 first symbols:codetok
4555
4556 cannot reachend
4557*/
4558
4559static void Rules (pge_SetOfStop stopset)
4560{
4561 Expect (bnflex_codetok, stopset|(pge_SetOfStop) ((1 << (bnflex_rulestok-bnflex_identtok))));
4562 Expect (bnflex_rulestok, stopset|(pge_SetOfStop) ((1 << (bnflex_symfunctok-bnflex_identtok)) | (1 << (bnflex_tfunctok-bnflex_identtok)) | (1 << (bnflex_errortok-bnflex_identtok)) | (1 << (bnflex_tokentok-bnflex_identtok)) | (1 << (bnflex_specialtok-bnflex_identtok)) | (1 << (bnflex_BNFtok-bnflex_identtok))));
4563 while ((((1 << (bnflex_GetCurrentTokenType ())) & ((unsigned int) ((1 << (bnflex_specialtok)) | (1 << (bnflex_tokentok)) | (1 << (bnflex_errortok)) | (1 << (bnflex_tfunctok)) | (1 << (bnflex_symfunctok))))) != 0))
4564 {
4565 Defs (stopset|(pge_SetOfStop) ((1 << (bnflex_BNFtok-bnflex_identtok)) | (1 << (bnflex_specialtok-bnflex_identtok)) | (1 << (bnflex_tokentok-bnflex_identtok)) | (1 << (bnflex_errortok-bnflex_identtok)) | (1 << (bnflex_tfunctok-bnflex_identtok)) | (1 << (bnflex_symfunctok-bnflex_identtok))));
4566 }
4567 /* while */
4568 ExtBNF (stopset);
4569}
4570
4571
4572/*
4573 Special := Ident
4574 % VAR p: ProductionDesc ; %
4575
4576 % p := NewProduction() ;
4577 p^.statement := NewStatement() ;
4578 p^.statement^.followinfo^.calcfollow := TRUE ;
4579 p^.statement^.followinfo^.epsilon := false ;
4580 p^.statement^.followinfo^.reachend := false ;
4581 p^.statement^.ident := CurrentIdent ;
4582 p^.statement^.expr := NIL ;
4583 p^.firstsolved := TRUE ;
4584 p^.followinfo^.calcfollow := TRUE ;
4585 p^.followinfo^.epsilon := false ;
4586 p^.followinfo^.reachend := false %
4587 First Follow [ 'epsilon'
4588 % p^.statement^.followinfo^.epsilon := true ; these are not used - but they are displayed when debugging
4589 p^.statement^.followinfo^.reachend := true ;
4590 p^.followinfo^.epsilon := true ;
4591 p^.followinfo^.reachend := true
4592 %
4593 ] [ Literal
4594 % p^.description := LastLiteral %
4595 ]
4596
4597 first symbols:identtok
4598
4599 cannot reachend
4600*/
4601
4602static void Special (pge_SetOfStop stopset)
4603{
4604 pge_ProductionDesc p;
4605
4606 Ident (stopset|(pge_SetOfStop) ((1 << (bnflex_firsttok-bnflex_identtok))));
4607 p = NewProduction ();
4608 p->statement = NewStatement ();
4609 p->statement->followinfo->calcfollow = TRUE;
4610 p->statement->followinfo->epsilon = pge_false;
4611 p->statement->followinfo->reachend = pge_false;
4612 p->statement->ident = CurrentIdent;
4613 p->statement->expr = NULL;
4614 p->firstsolved = TRUE;
4615 p->followinfo->calcfollow = TRUE;
4616 p->followinfo->epsilon = pge_false;
4617 p->followinfo->reachend = pge_false;
4618 First (stopset|(pge_SetOfStop) ((1 << (bnflex_followtok-bnflex_identtok))));
4619 Follow (stopset|(pge_SetOfStop) ((1 << (bnflex_epsilontok-bnflex_identtok)) | (1 << (bnflex_squotetok-bnflex_identtok)) | (1 << (bnflex_dquotetok-bnflex_identtok))));
4620 if ((bnflex_GetCurrentTokenType ()) == bnflex_epsilontok)
4621 {
4622 Expect (bnflex_epsilontok, stopset|(pge_SetOfStop) ((1 << (bnflex_dquotetok-bnflex_identtok)) | (1 << (bnflex_squotetok-bnflex_identtok))));
4623 p->statement->followinfo->epsilon = pge_true; /* these are not used - but they are displayed when debugging */
4624 p->statement->followinfo->reachend = pge_true; /* these are not used - but they are displayed when debugging */
4625 p->followinfo->epsilon = pge_true;
4626 p->followinfo->reachend = pge_true;
4627 }
4628 if ((((1 << (bnflex_GetCurrentTokenType ())) & ((unsigned int) ((1 << (bnflex_dquotetok)) | (1 << (bnflex_squotetok))))) != 0))
4629 {
4630 Literal (stopset);
4631 p->description = LastLiteral;
4632 }
4633}
4634
4635
4636/*
4637 Factor := '%' Modula2Code '%' |
4638 Ident
4639 % WITH CurrentFactor^ DO
4640 type := id ;
4641 ident := CurrentIdent
4642 END ; %
4643 | Literal
4644 % WITH CurrentFactor^ DO
4645 type := lit ;
4646 string := LastLiteral ;
4647 IF GetSymKey(Aliases, LastLiteral)=NulName
4648 THEN
4649 WarnError1('no token defined for literal %s', LastLiteral)
4650 END
4651 END ; %
4652 | '{'
4653 % WITH CurrentFactor^ DO
4654 type := mult ;
4655 expr := NewExpression() ;
4656 CurrentExpression := expr ;
4657 END ; %
4658 Expression '}' | '['
4659 % WITH CurrentFactor^ DO
4660 type := opt ;
4661 expr := NewExpression() ;
4662 CurrentExpression := expr ;
4663 END ; %
4664 Expression ']' | '('
4665 % WITH CurrentFactor^ DO
4666 type := sub ;
4667 expr := NewExpression() ;
4668 CurrentExpression := expr ;
4669 END ; %
4670 Expression ')'
4671
4672 first symbols:dquotetok, squotetok, lparatok, lsparatok, lcparatok, identtok, codetok
4673
4674 cannot reachend
4675*/
4676
4677static void Factor (pge_SetOfStop stopset)
4678{
4679 if ((bnflex_GetCurrentTokenType ()) == bnflex_codetok)
4680 {
4681 Expect (bnflex_codetok, stopset);
4682 Modula2Code (stopset|(pge_SetOfStop) ((1 << (bnflex_codetok-bnflex_identtok))));
4683 Expect (bnflex_codetok, stopset);
4684 }
4685 else if ((bnflex_GetCurrentTokenType ()) == bnflex_identtok)
4686 {
4687 /* avoid dangling else. */
4688 Ident (stopset);
4689 CurrentFactor->type = pge_id;
4690 CurrentFactor->ident = CurrentIdent;
4691 }
4692 else if ((((1 << (bnflex_GetCurrentTokenType ())) & ((unsigned int) ((1 << (bnflex_dquotetok)) | (1 << (bnflex_squotetok))))) != 0))
4693 {
4694 /* avoid dangling else. */
4695 Literal (stopset);
4696 CurrentFactor->type = pge_lit;
4697 CurrentFactor->string = LastLiteral;
4698 if ((SymbolKey_GetSymKey (Aliases, LastLiteral)) == NameKey_NulName)
4699 {
4700 WarnError1 ((const char *) "no token defined for literal %s", 31, LastLiteral);
4701 }
4702 }
4703 else if ((bnflex_GetCurrentTokenType ()) == bnflex_lcparatok)
4704 {
4705 /* avoid dangling else. */
4706 Expect (bnflex_lcparatok, stopset|(pge_SetOfStop) ((1 << (bnflex_lparatok-bnflex_identtok)) | (1 << (bnflex_lsparatok-bnflex_identtok)) | (1 << (bnflex_lcparatok-bnflex_identtok)) | (1 << (bnflex_identtok-bnflex_identtok)) | (1 << (bnflex_codetok-bnflex_identtok)) | (1 << (bnflex_dquotetok-bnflex_identtok)) | (1 << (bnflex_squotetok-bnflex_identtok))));
4707 CurrentFactor->type = pge_mult;
4708 CurrentFactor->expr = NewExpression ();
4709 CurrentExpression = CurrentFactor->expr;
4710 Expression (stopset|(pge_SetOfStop) ((1 << (bnflex_rcparatok-bnflex_identtok))));
4711 Expect (bnflex_rcparatok, stopset);
4712 }
4713 else if ((bnflex_GetCurrentTokenType ()) == bnflex_lsparatok)
4714 {
4715 /* avoid dangling else. */
4716 Expect (bnflex_lsparatok, stopset|(pge_SetOfStop) ((1 << (bnflex_lparatok-bnflex_identtok)) | (1 << (bnflex_lsparatok-bnflex_identtok)) | (1 << (bnflex_lcparatok-bnflex_identtok)) | (1 << (bnflex_identtok-bnflex_identtok)) | (1 << (bnflex_codetok-bnflex_identtok)) | (1 << (bnflex_dquotetok-bnflex_identtok)) | (1 << (bnflex_squotetok-bnflex_identtok))));
4717 CurrentFactor->type = pge_opt;
4718 CurrentFactor->expr = NewExpression ();
4719 CurrentExpression = CurrentFactor->expr;
4720 Expression (stopset|(pge_SetOfStop) ((1 << (bnflex_rsparatok-bnflex_identtok))));
4721 Expect (bnflex_rsparatok, stopset);
4722 }
4723 else if ((bnflex_GetCurrentTokenType ()) == bnflex_lparatok)
4724 {
4725 /* avoid dangling else. */
4726 Expect (bnflex_lparatok, stopset|(pge_SetOfStop) ((1 << (bnflex_lparatok-bnflex_identtok)) | (1 << (bnflex_lsparatok-bnflex_identtok)) | (1 << (bnflex_lcparatok-bnflex_identtok)) | (1 << (bnflex_identtok-bnflex_identtok)) | (1 << (bnflex_codetok-bnflex_identtok)) | (1 << (bnflex_dquotetok-bnflex_identtok)) | (1 << (bnflex_squotetok-bnflex_identtok))));
4727 CurrentFactor->type = pge_sub;
4728 CurrentFactor->expr = NewExpression ();
4729 CurrentExpression = CurrentFactor->expr;
4730 Expression (stopset|(pge_SetOfStop) ((1 << (bnflex_rparatok-bnflex_identtok))));
4731 Expect (bnflex_rparatok, stopset);
4732 }
4733 else
4734 {
4735 /* avoid dangling else. */
4736 PushBackInput_WarnError ((const char *) "expecting one of: ( [ { \" single quote identifier %", 51);
4737 }
4738}
4739
4740
4741/*
4742 Statement :=
4743 % VAR i: IdentDesc ; %
4744 Ident
4745 % VAR p: ProductionDesc ; %
4746
4747 % p := FindDefinition(CurrentIdent^.name) ;
4748 IF p=NIL
4749 THEN
4750 p := NewProduction()
4751 ELSE
4752 IF NOT ((p^.statement=NIL) OR (p^.statement^.expr=NIL))
4753 THEN
4754 WarnError1('already declared rule %s', CurrentIdent^.name)
4755 END
4756 END ;
4757 i := CurrentIdent ; %
4758 ':='
4759 % VAR e: ExpressionDesc ; %
4760
4761 % e := NewExpression() ;
4762 CurrentExpression := e ; %
4763
4764 % VAR s: StatementDesc ; %
4765
4766 % s := NewStatement() ;
4767 WITH s^ DO
4768 ident := i ;
4769 expr := e
4770 END ; %
4771 Expression
4772 % p^.statement := s ; %
4773 '=:'
4774
4775 first symbols:identtok
4776
4777 cannot reachend
4778*/
4779
4780static void Statement (pge_SetOfStop stopset)
4781{
4782 pge_IdentDesc i;
4783 pge_ProductionDesc p;
4784 pge_ExpressionDesc e;
4785 pge_StatementDesc s;
4786
4787 Ident (stopset|(pge_SetOfStop) ((1 << (bnflex_lbecomestok-bnflex_identtok))));
4788 p = FindDefinition (CurrentIdent->name);
4789 if (p == NULL)
4790 {
4791 p = NewProduction ();
4792 }
4793 else
4794 {
4795 if (! ((p->statement == NULL) || (p->statement->expr == NULL)))
4796 {
4797 WarnError1 ((const char *) "already declared rule %s", 24, CurrentIdent->name);
4798 }
4799 }
4800 i = CurrentIdent;
4801 Expect (bnflex_lbecomestok, stopset|(pge_SetOfStop) ((1 << (bnflex_lparatok-bnflex_identtok)) | (1 << (bnflex_lsparatok-bnflex_identtok)) | (1 << (bnflex_lcparatok-bnflex_identtok)) | (1 << (bnflex_identtok-bnflex_identtok)) | (1 << (bnflex_codetok-bnflex_identtok)) | (1 << (bnflex_dquotetok-bnflex_identtok)) | (1 << (bnflex_squotetok-bnflex_identtok))));
4802 e = NewExpression ();
4803 CurrentExpression = e;
4804 s = NewStatement ();
4805 s->ident = i;
4806 s->expr = e;
4807 Expression (stopset|(pge_SetOfStop) ((1 << (bnflex_rbecomestok-bnflex_identtok))));
4808 p->statement = s;
4809 Expect (bnflex_rbecomestok, stopset);
4810}
4811
4812
4813/*
4814 Defs := 'special' Special | 'token' Token |
4815 'error' ErrorProcedures |
4816 'tokenfunc' TokenProcedure |
4817 'symfunc' SymProcedure
4818
4819 first symbols:symfunctok, tfunctok, errortok, tokentok, specialtok
4820
4821 cannot reachend
4822*/
4823
4824static void Defs (pge_SetOfStop stopset)
4825{
4826 if ((bnflex_GetCurrentTokenType ()) == bnflex_specialtok)
4827 {
4828 Expect (bnflex_specialtok, stopset|(pge_SetOfStop) ((1 << (bnflex_identtok-bnflex_identtok))));
4829 Special (stopset);
4830 }
4831 else if ((bnflex_GetCurrentTokenType ()) == bnflex_tokentok)
4832 {
4833 /* avoid dangling else. */
4834 Expect (bnflex_tokentok, stopset|(pge_SetOfStop) ((1 << (bnflex_dquotetok-bnflex_identtok)) | (1 << (bnflex_squotetok-bnflex_identtok))));
4835 Token (stopset);
4836 }
4837 else if ((bnflex_GetCurrentTokenType ()) == bnflex_errortok)
4838 {
4839 /* avoid dangling else. */
4840 Expect (bnflex_errortok, stopset|(pge_SetOfStop) ((1 << (bnflex_dquotetok-bnflex_identtok)) | (1 << (bnflex_squotetok-bnflex_identtok))));
4841 ErrorProcedures (stopset);
4842 }
4843 else if ((bnflex_GetCurrentTokenType ()) == bnflex_tfunctok)
4844 {
4845 /* avoid dangling else. */
4846 Expect (bnflex_tfunctok, stopset|(pge_SetOfStop) ((1 << (bnflex_dquotetok-bnflex_identtok)) | (1 << (bnflex_squotetok-bnflex_identtok))));
4847 TokenProcedure (stopset);
4848 }
4849 else if ((bnflex_GetCurrentTokenType ()) == bnflex_symfunctok)
4850 {
4851 /* avoid dangling else. */
4852 Expect (bnflex_symfunctok, stopset|(pge_SetOfStop) ((1 << (bnflex_dquotetok-bnflex_identtok)) | (1 << (bnflex_squotetok-bnflex_identtok))));
4853 SymProcedure (stopset);
4854 }
4855 else
4856 {
4857 /* avoid dangling else. */
4858 PushBackInput_WarnError ((const char *) "expecting one of: symfunc tokenfunc error token special", 55);
4859 }
4860}
4861
4862
4863/*
4864 ExtBNF := 'BNF' { Production } 'FNB'
4865
4866 first symbols:BNFtok
4867
4868 cannot reachend
4869*/
4870
4871static void ExtBNF (pge_SetOfStop stopset)
4872{
4873 Expect (bnflex_BNFtok, stopset|(pge_SetOfStop) ((1 << (bnflex_FNBtok-bnflex_identtok)) | (1 << (bnflex_identtok-bnflex_identtok))));
4874 while ((bnflex_GetCurrentTokenType ()) == bnflex_identtok)
4875 {
4876 Production (stopset|(pge_SetOfStop) ((1 << (bnflex_FNBtok-bnflex_identtok)) | (1 << (bnflex_identtok-bnflex_identtok))));
4877 }
4878 /* while */
4879 Expect (bnflex_FNBtok, stopset);
4880}
4881
4882
4883/*
4884 Main := Header Decls Footer Rules
4885
4886 first symbols:codetok
4887
4888 cannot reachend
4889*/
4890
4891static void Main (pge_SetOfStop stopset)
4892{
4893 Header (stopset|(pge_SetOfStop) ((1 << (bnflex_codetok-bnflex_identtok))));
4894 Decls (stopset|(pge_SetOfStop) ((1 << (bnflex_codetok-bnflex_identtok))));
4895 Footer (stopset|(pge_SetOfStop) ((1 << (bnflex_codetok-bnflex_identtok))));
4896 Rules (stopset);
4897}
4898
4899
4900/*
4901 Header := '%' 'module' StartModName
4902
4903 first symbols:codetok
4904
4905 cannot reachend
4906*/
4907
4908static void Header (pge_SetOfStop stopset)
4909{
4910 Expect (bnflex_codetok, stopset|(pge_SetOfStop) ((1 << (bnflex_moduletok-bnflex_identtok))));
4911 Expect (bnflex_moduletok, stopset|(pge_SetOfStop) ((1 << (bnflex_identtok-bnflex_identtok))));
4912 StartModName (stopset);
4913}
4914
4915
4916/*
4917 Decls := '%' 'declaration' DoDeclaration
4918
4919 first symbols:codetok
4920
4921 cannot reachend
4922*/
4923
4924static void Decls (pge_SetOfStop stopset)
4925{
4926 Expect (bnflex_codetok, stopset|(pge_SetOfStop) ((1 << (bnflex_declarationtok-bnflex_identtok))));
4927 Expect (bnflex_declarationtok, stopset|(pge_SetOfStop) ((1 << (bnflex_identtok-bnflex_identtok))));
4928 DoDeclaration (stopset);
4929}
4930
4931
4932/*
4933 Footer := '%' 'module' EndModName
4934
4935 first symbols:codetok
4936
4937 cannot reachend
4938*/
4939
4940static void Footer (pge_SetOfStop stopset)
4941{
4942 Expect (bnflex_codetok, stopset|(pge_SetOfStop) ((1 << (bnflex_moduletok-bnflex_identtok))));
4943 Expect (bnflex_moduletok, stopset|(pge_SetOfStop) ((1 << (bnflex_identtok-bnflex_identtok))));
4944 EndModName (stopset);
4945}
4946
4947
4948/*
4949 First := 'first' '{' { LitOrTokenOrIdent
4950 % WITH CurrentSetDesc^ DO
4951 next := TailProduction^.first ;
4952 END ;
4953 TailProduction^.first := CurrentSetDesc
4954 %
4955 } '}'
4956
4957 first symbols:firsttok
4958
4959 cannot reachend
4960*/
4961
4962static void First (pge_SetOfStop stopset)
4963{
4964 Expect (bnflex_firsttok, stopset|(pge_SetOfStop) ((1 << (bnflex_lcparatok-bnflex_identtok))));
4965 Expect (bnflex_lcparatok, stopset|(pge_SetOfStop) ((1 << (bnflex_rcparatok-bnflex_identtok)) | (1 << (bnflex_identtok-bnflex_identtok)) | (1 << (bnflex_lesstok-bnflex_identtok)) | (1 << (bnflex_dquotetok-bnflex_identtok)) | (1 << (bnflex_squotetok-bnflex_identtok))));
4966 while ((((1 << (bnflex_GetCurrentTokenType ())) & ((unsigned int) ((1 << (bnflex_lesstok)) | (1 << (bnflex_identtok)) | (1 << (bnflex_squotetok)) | (1 << (bnflex_dquotetok))))) != 0))
4967 {
4968 LitOrTokenOrIdent (stopset|(pge_SetOfStop) ((1 << (bnflex_rcparatok-bnflex_identtok)) | (1 << (bnflex_lesstok-bnflex_identtok)) | (1 << (bnflex_identtok-bnflex_identtok)) | (1 << (bnflex_squotetok-bnflex_identtok)) | (1 << (bnflex_dquotetok-bnflex_identtok))));
4969 CurrentSetDesc->next = TailProduction->first;
4970 TailProduction->first = CurrentSetDesc;
4971 }
4972 /* while */
4973 Expect (bnflex_rcparatok, stopset);
4974}
4975
4976
4977/*
4978 Follow := 'follow' '{' { LitOrTokenOrIdent
4979 % WITH CurrentSetDesc^ DO
4980 next := TailProduction^.followinfo^.follow ;
4981 END ;
4982 TailProduction^.followinfo^.follow := CurrentSetDesc
4983 %
4984 } '}'
4985
4986 first symbols:followtok
4987
4988 cannot reachend
4989*/
4990
4991static void Follow (pge_SetOfStop stopset)
4992{
4993 Expect (bnflex_followtok, stopset|(pge_SetOfStop) ((1 << (bnflex_lcparatok-bnflex_identtok))));
4994 Expect (bnflex_lcparatok, stopset|(pge_SetOfStop) ((1 << (bnflex_rcparatok-bnflex_identtok)) | (1 << (bnflex_identtok-bnflex_identtok)) | (1 << (bnflex_lesstok-bnflex_identtok)) | (1 << (bnflex_dquotetok-bnflex_identtok)) | (1 << (bnflex_squotetok-bnflex_identtok))));
4995 while ((((1 << (bnflex_GetCurrentTokenType ())) & ((unsigned int) ((1 << (bnflex_lesstok)) | (1 << (bnflex_identtok)) | (1 << (bnflex_squotetok)) | (1 << (bnflex_dquotetok))))) != 0))
4996 {
4997 LitOrTokenOrIdent (stopset|(pge_SetOfStop) ((1 << (bnflex_rcparatok-bnflex_identtok)) | (1 << (bnflex_lesstok-bnflex_identtok)) | (1 << (bnflex_identtok-bnflex_identtok)) | (1 << (bnflex_squotetok-bnflex_identtok)) | (1 << (bnflex_dquotetok-bnflex_identtok))));
4998 CurrentSetDesc->next = TailProduction->followinfo->follow;
4999 TailProduction->followinfo->follow = CurrentSetDesc;
5000 }
5001 /* while */
5002 Expect (bnflex_rcparatok, stopset);
5003}
5004
5005
5006/*
5007 LitOrTokenOrIdent := Literal
5008 % CurrentSetDesc := NewSetDesc() ;
5009 WITH CurrentSetDesc^ DO
5010 type := litel ;
5011 string := LastLiteral ;
5012 END ;
5013 %
5014 | '<' CollectTok '>' |
5015 Ident
5016 % CurrentSetDesc := NewSetDesc() ;
5017 WITH CurrentSetDesc^ DO
5018 type := idel ;
5019 ident := CurrentIdent ;
5020 END ;
5021 %
5022
5023
5024 first symbols:dquotetok, squotetok, identtok, lesstok
5025
5026 cannot reachend
5027*/
5028
5029static void LitOrTokenOrIdent (pge_SetOfStop stopset)
5030{
5031 if ((((1 << (bnflex_GetCurrentTokenType ())) & ((unsigned int) ((1 << (bnflex_dquotetok)) | (1 << (bnflex_squotetok))))) != 0))
5032 {
5033 Literal (stopset);
5034 CurrentSetDesc = NewSetDesc ();
5035 CurrentSetDesc->type = pge_litel;
5036 CurrentSetDesc->string = LastLiteral;
5037 }
5038 else if ((bnflex_GetCurrentTokenType ()) == bnflex_lesstok)
5039 {
5040 /* avoid dangling else. */
5041 Expect (bnflex_lesstok, stopset|(pge_SetOfStop) ((1 << (bnflex_identtok-bnflex_identtok))));
5042 CollectTok (stopset|(pge_SetOfStop) ((1 << (bnflex_gretok-bnflex_identtok))));
5043 Expect (bnflex_gretok, stopset);
5044 }
5045 else if ((bnflex_GetCurrentTokenType ()) == bnflex_identtok)
5046 {
5047 /* avoid dangling else. */
5048 Ident (stopset);
5049 CurrentSetDesc = NewSetDesc ();
5050 CurrentSetDesc->type = pge_idel;
5051 CurrentSetDesc->ident = CurrentIdent;
5052 }
5053 else
5054 {
5055 /* avoid dangling else. */
5056 PushBackInput_WarnError ((const char *) "expecting one of: identifier < \" single quote", 45);
5057 }
5058}
5059
5060
5061/*
5062 Literal := '"' CollectLiteral '"' |
5063 "'" CollectLiteral "'"
5064
5065 first symbols:squotetok, dquotetok
5066
5067 cannot reachend
5068*/
5069
5070static void Literal (pge_SetOfStop stopset)
5071{
5072 if ((bnflex_GetCurrentTokenType ()) == bnflex_dquotetok)
5073 {
5074 Expect (bnflex_dquotetok, stopset|(pge_SetOfStop) ((1 << (bnflex_literaltok-bnflex_identtok))));
5075 CollectLiteral (stopset|(pge_SetOfStop) ((1 << (bnflex_dquotetok-bnflex_identtok))));
5076 Expect (bnflex_dquotetok, stopset);
5077 }
5078 else if ((bnflex_GetCurrentTokenType ()) == bnflex_squotetok)
5079 {
5080 /* avoid dangling else. */
5081 Expect (bnflex_squotetok, stopset|(pge_SetOfStop) ((1 << (bnflex_literaltok-bnflex_identtok))));
5082 CollectLiteral (stopset|(pge_SetOfStop) ((1 << (bnflex_squotetok-bnflex_identtok))));
5083 Expect (bnflex_squotetok, stopset);
5084 }
5085 else
5086 {
5087 /* avoid dangling else. */
5088 PushBackInput_WarnError ((const char *) "expecting one of: single quote \"", 32);
5089 }
5090}
5091
5092
5093/*
5094 Token := Literal DefineToken
5095
5096 first symbols:dquotetok, squotetok
5097
5098 cannot reachend
5099*/
5100
5101static void Token (pge_SetOfStop stopset)
5102{
5103 Literal (stopset|(pge_SetOfStop) ((1 << (bnflex_identtok-bnflex_identtok))));
5104 DefineToken (stopset);
5105}
5106
5107
5108/*
5109 ErrorProcedures := Literal
5110 % ErrorProcArray := LastLiteral %
5111 Literal
5112 % ErrorProcString := LastLiteral %
5113
5114
5115 first symbols:dquotetok, squotetok
5116
5117 cannot reachend
5118*/
5119
5120static void ErrorProcedures (pge_SetOfStop stopset)
5121{
5122 Literal (stopset|(pge_SetOfStop) ((1 << (bnflex_squotetok-bnflex_identtok)) | (1 << (bnflex_dquotetok-bnflex_identtok))));
5123 ErrorProcArray = LastLiteral;
5124 Literal (stopset);
5125 ErrorProcString = LastLiteral;
5126}
5127
5128
5129/*
5130 TokenProcedure := Literal
5131 % TokenTypeProc := LastLiteral %
5132
5133
5134 first symbols:dquotetok, squotetok
5135
5136 cannot reachend
5137*/
5138
5139static void TokenProcedure (pge_SetOfStop stopset)
5140{
5141 Literal (stopset);
5142 TokenTypeProc = LastLiteral;
5143}
5144
5145
5146/*
5147 SymProcedure := Literal
5148 % SymIsProc := LastLiteral %
5149
5150
5151 first symbols:dquotetok, squotetok
5152
5153 cannot reachend
5154*/
5155
5156static void SymProcedure (pge_SetOfStop stopset)
5157{
5158 Literal (stopset);
5159 SymIsProc = LastLiteral;
5160}
5161
5162
5163/*
5164 Production := Statement
5165
5166 first symbols:identtok
5167
5168 cannot reachend
5169*/
5170
5171static void Production (pge_SetOfStop stopset)
5172{
5173 Statement (stopset);
5174}
5175
5176
5177/*
5178 Expression :=
5179 % VAR t1, t2: TermDesc ;
5180 e : ExpressionDesc ; %
5181
5182 % e := CurrentExpression ;
5183 t1 := NewTerm() ;
5184 CurrentTerm := t1 ; %
5185 Term
5186 % e^.term := t1 ; %
5187 { '|'
5188 % t2 := NewTerm() ;
5189 CurrentTerm := t2 %
5190 Term
5191 % t1^.next := t2 ;
5192 t1 := t2 %
5193 }
5194
5195 first symbols:dquotetok, squotetok, lparatok, lsparatok, lcparatok, identtok, codetok
5196
5197 cannot reachend
5198*/
5199
5200static void Expression (pge_SetOfStop stopset)
5201{
5202 pge_TermDesc t1;
5203 pge_TermDesc t2;
5204 pge_ExpressionDesc e;
5205
5206 e = CurrentExpression;
5207 t1 = NewTerm ();
5208 CurrentTerm = t1;
5209 Term (stopset|(pge_SetOfStop) ((1 << (bnflex_bartok-bnflex_identtok))));
5210 e->term = t1;
5211 while ((bnflex_GetCurrentTokenType ()) == bnflex_bartok)
5212 {
5213 Expect (bnflex_bartok, stopset|(pge_SetOfStop) ((1 << (bnflex_codetok-bnflex_identtok)) | (1 << (bnflex_identtok-bnflex_identtok)) | (1 << (bnflex_lcparatok-bnflex_identtok)) | (1 << (bnflex_lsparatok-bnflex_identtok)) | (1 << (bnflex_lparatok-bnflex_identtok)) | (1 << (bnflex_squotetok-bnflex_identtok)) | (1 << (bnflex_dquotetok-bnflex_identtok))));
5214 t2 = NewTerm ();
5215 CurrentTerm = t2;
5216 Term (stopset|(pge_SetOfStop) ((1 << (bnflex_bartok-bnflex_identtok))));
5217 t1->next = t2;
5218 t1 = t2;
5219 }
5220 /* while */
5221}
5222
5223
5224/*
5225 Term :=
5226 % VAR t1: TermDesc ; f1, f2: FactorDesc ; %
5227
5228 % CurrentFactor := NewFactor() ;
5229 f1 := CurrentFactor ;
5230 t1 := CurrentTerm ; %
5231 Factor
5232 % t1^.factor := f1 ;
5233 f2 := NewFactor() ;
5234 CurrentFactor := f2 %
5235 { Factor
5236 % f1^.next := f2 ;
5237 f1 := f2 ;
5238 f2 := NewFactor() ;
5239 CurrentFactor := f2 ; %
5240 }
5241
5242 first symbols:squotetok, dquotetok, codetok, identtok, lcparatok, lsparatok, lparatok
5243
5244 cannot reachend
5245*/
5246
5247static void Term (pge_SetOfStop stopset)
5248{
5249 pge_TermDesc t1;
5250 pge_FactorDesc f1;
5251 pge_FactorDesc f2;
5252
5253 CurrentFactor = NewFactor ();
5254 f1 = CurrentFactor;
5255 t1 = CurrentTerm;
5256 Factor (stopset|(pge_SetOfStop) ((1 << (bnflex_lparatok-bnflex_identtok)) | (1 << (bnflex_lsparatok-bnflex_identtok)) | (1 << (bnflex_lcparatok-bnflex_identtok)) | (1 << (bnflex_identtok-bnflex_identtok)) | (1 << (bnflex_codetok-bnflex_identtok)) | (1 << (bnflex_dquotetok-bnflex_identtok)) | (1 << (bnflex_squotetok-bnflex_identtok))));
5257 t1->factor = f1;
5258 f2 = NewFactor ();
5259 CurrentFactor = f2;
5260 while ((((1 << (bnflex_GetCurrentTokenType ())) & ((unsigned int) ((1 << (bnflex_codetok)) | (1 << (bnflex_identtok)) | (1 << (bnflex_lcparatok)) | (1 << (bnflex_lsparatok)) | (1 << (bnflex_lparatok)) | (1 << (bnflex_squotetok)) | (1 << (bnflex_dquotetok))))) != 0))
5261 {
5262 Factor (stopset|(pge_SetOfStop) ((1 << (bnflex_codetok-bnflex_identtok)) | (1 << (bnflex_identtok-bnflex_identtok)) | (1 << (bnflex_lcparatok-bnflex_identtok)) | (1 << (bnflex_lsparatok-bnflex_identtok)) | (1 << (bnflex_lparatok-bnflex_identtok)) | (1 << (bnflex_squotetok-bnflex_identtok)) | (1 << (bnflex_dquotetok-bnflex_identtok))));
5263 f1->next = f2;
5264 f1 = f2;
5265 f2 = NewFactor ();
5266 CurrentFactor = f2;
5267 }
5268 /* while */
5269}
5270
5271
5272/*
5273 GetDefinitionName - returns the name of the rule inside, p.
5274*/
5275
5276static NameKey_Name GetDefinitionName (pge_ProductionDesc p)
5277{
5278 if (p != NULL)
5279 {
5280 if ((p->statement != NULL) && (p->statement->ident != NULL))
5281 {
5282 return p->statement->ident->name;
5283 }
5284 }
5285 return NameKey_NulName;
5286 /* static analysis guarentees a RETURN statement will be used before here. */
5287 __builtin_unreachable ();
5288}
5289
5290
5291/*
5292 FindDefinition - searches and returns the rule which defines, n.
5293*/
5294
5295static pge_ProductionDesc FindDefinition (NameKey_Name n)
5296{
5297 pge_ProductionDesc p;
5298 pge_ProductionDesc f;
5299
5300 p = HeadProduction;
5301 f = NULL;
5302 while (p != NULL)
5303 {
5304 if ((GetDefinitionName (p)) == n)
5305 {
5306 /* avoid gcc warning by using compound statement even if not strictly necessary. */
5307 if (f == NULL)
5308 {
5309 f = p;
5310 }
5311 else
5312 {
5313 StrIO_WriteString ((const char *) "multiple definition for rule: ", 30);
5314 NameKey_WriteKey (n);
5315 StrIO_WriteLn ();
5316 }
5317 }
5318 p = p->next;
5319 }
5320 return f;
5321 /* static analysis guarentees a RETURN statement will be used before here. */
5322 __builtin_unreachable ();
5323}
5324
5325
5326/*
5327 BackPatchIdent - found an ident, i, we must look for the corresponding rule and
5328 set the definition accordingly.
5329*/
5330
5331static void BackPatchIdent (pge_IdentDesc i)
5332{
5333 if (i != NULL)
5334 {
5335 i->definition = FindDefinition (i->name);
5336 if (i->definition == NULL)
5337 {
5338 WarnError1 ((const char *) "unable to find production %s", 28, i->name);
5339 WasNoError = FALSE;
5340 }
5341 }
5342}
5343
5344
5345/*
5346 BackPatchFactor - runs through the factor looking for an ident
5347*/
5348
5349static void BackPatchFactor (pge_FactorDesc f)
5350{
5351 while (f != NULL)
5352 {
5353 switch (f->type)
5354 {
5355 case pge_id:
5356 BackPatchIdent (f->ident);
5357 break;
5358
5359 case pge_sub:
5360 case pge_opt:
5361 case pge_mult:
5362 BackPatchExpression (f->expr);
5363 break;
5364
5365
5366 default:
5367 break;
5368 }
5369 f = f->next;
5370 }
5371}
5372
5373
5374/*
5375 BackPatchTerm - runs through all terms to find idents.
5376*/
5377
5378static void BackPatchTerm (pge_TermDesc t)
5379{
5380 while (t != NULL)
5381 {
5382 BackPatchFactor (t->factor);
5383 t = t->next;
5384 }
5385}
5386
5387
5388/*
5389 BackPatchExpression - runs through the term to find any idents.
5390*/
5391
5392static void BackPatchExpression (pge_ExpressionDesc e)
5393{
5394 if (e != NULL)
5395 {
5396 BackPatchTerm (e->term);
5397 }
5398}
5399
5400
5401/*
5402 BackPatchSet -
5403*/
5404
5405static void BackPatchSet (pge_SetDesc s)
5406{
5407 while (s != NULL)
5408 {
5409 switch (s->type)
5410 {
5411 case pge_idel:
5412 BackPatchIdent (s->ident);
5413 break;
5414
5415
5416 default:
5417 break;
5418 }
5419 s = s->next;
5420 }
5421}
5422
5423
5424/*
5425 BackPatchIdentToDefinitions - search through all the rules and add a link from any ident
5426 to the definition.
5427*/
5428
5429static void BackPatchIdentToDefinitions (pge_ProductionDesc d)
5430{
5431 if ((d != NULL) && (d->statement != NULL))
5432 {
5433 BackPatchExpression (d->statement->expr);
5434 }
5435}
5436
5437
5438/*
5439 CalculateFirstAndFollow -
5440*/
5441
5442static void CalculateFirstAndFollow (pge_ProductionDesc p)
5443{
5444 if (Debugging)
5445 {
5446 StrIO_WriteLn ();
5447 NameKey_WriteKey (p->statement->ident->name);
5448 StrIO_WriteLn ();
5449 StrIO_WriteString ((const char *) " calculating first", 19);
5450 }
5451 CalcFirstProduction (p, p, &p->first);
5452 BackPatchSet (p->first);
5453 if (Debugging)
5454 {
5455 StrIO_WriteString ((const char *) " calculating follow set", 24);
5456 }
5457 if (p->followinfo->follow == NULL)
5458 {
5459 CalcFollowProduction (p);
5460 }
5461 BackPatchSet (p->followinfo->follow);
5462}
5463
5464
5465/*
5466 ForeachRuleDo -
5467*/
5468
5469static void ForeachRuleDo (pge_DoProcedure p)
5470{
5471 CurrentProduction = HeadProduction;
5472 while (CurrentProduction != NULL)
5473 {
5474 (*p.proc) (CurrentProduction);
5475 CurrentProduction = CurrentProduction->next;
5476 }
5477}
5478
5479
5480/*
5481 WhileNotCompleteDo -
5482*/
5483
5484static void WhileNotCompleteDo (pge_DoProcedure p)
5485{
5486 do {
5487 Finished = TRUE;
5488 ForeachRuleDo (p);
5489 } while (! (Finished));
5490}
5491
5492
5493/*
5494 NewLine - generate a newline and indent.
5495*/
5496
5497static void NewLine (unsigned int Left)
5498{
5499 Output_WriteLn ();
5500 BeginningOfLine = TRUE;
5501 Indent = 0;
5502 while (Indent < Left)
5503 {
5504 Output_Write (' ');
5505 Indent += 1;
5506 }
5507}
5508
5509
5510/*
5511 CheckNewLine -
5512*/
5513
5514static void CheckNewLine (unsigned int Left)
5515{
5516 if (Indent == Left)
5517 {
5518 Left = BaseNewLine;
5519 }
5520 if (Indent > BaseRightMargin)
5521 {
5522 NewLine (Left);
5523 }
5524}
5525
5526
5527/*
5528 IndentString - writes out a string with a preceeding indent.
5529*/
5530
5531static void IndentString (const char *a_, unsigned int _a_high)
5532{
5533 unsigned int i;
5534 char a[_a_high+1];
5535
5536 /* make a local copy of each unbounded array. */
5537 memcpy (a, a_, _a_high+1);
5538
5539 i = 0;
5540 while (i < Indent)
5541 {
5542 Output_Write (' ');
5543 i += 1;
5544 }
5545 Output_WriteString ((const char *) a, _a_high);
5546 LastLineNo = 0;
5547}
5548
5549
5550/*
5551 KeyWord - writes out a keywork with optional formatting directives.
5552*/
5553
5554static void KeyWord (NameKey_Name n)
5555{
5556 if (KeywordFormatting)
5557 {
5558 Output_WriteString ((const char *) "{%K", 3);
5559 if (((n == (NameKey_MakeKey ((const char *) "}", 1))) || (n == (NameKey_MakeKey ((const char *) "{", 1)))) || (n == (NameKey_MakeKey ((const char *) "%", 1))))
5560 {
5561 Output_Write ('%'); /* escape }, { or % */
5562 }
5563 Output_WriteKey (n);
5564 Output_Write ('}');
5565 }
5566 else
5567 {
5568 Output_WriteKey (n);
5569 }
5570}
5571
5572
5573/*
5574 PrettyPara -
5575*/
5576
5577static void PrettyPara (const char *c1_, unsigned int _c1_high, const char *c2_, unsigned int _c2_high, pge_ExpressionDesc e, unsigned int Left)
5578{
5579 char c1[_c1_high+1];
5580 char c2[_c2_high+1];
5581
5582 /* make a local copy of each unbounded array. */
5583 memcpy (c1, c1_, _c1_high+1);
5584 memcpy (c2, c2_, _c2_high+1);
5585
5586 Output_WriteString ((const char *) c1, _c1_high);
5587 Indent += StrLib_StrLen ((const char *) c1, _c1_high);
5588 Left = Indent;
5589 PrettyCommentExpression (e, Left);
5590 Output_WriteString ((const char *) c2, _c2_high);
5591 Indent += StrLib_StrLen ((const char *) c2, _c2_high);
5592}
5593
5594
5595/*
5596 WriteKeyTexinfo -
5597*/
5598
5599static void WriteKeyTexinfo (NameKey_Name s)
5600{
5601 DynamicStrings_String ds;
5602 char ch;
5603 unsigned int i;
5604 unsigned int l;
5605
5606 if (Texinfo)
5607 {
5608 ds = DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (s));
5609 l = DynamicStrings_Length (ds);
5610 i = 0;
5611 while (i < l)
5612 {
5613 ch = DynamicStrings_char (ds, static_cast<int> (i));
5614 if ((ch == '{') || (ch == '}'))
5615 {
5616 Output_Write ('@');
5617 }
5618 Output_Write (ch);
5619 i += 1;
5620 }
5621 }
5622 else
5623 {
5624 Output_WriteKey (s);
5625 }
5626}
5627
5628
5629/*
5630 PrettyCommentFactor -
5631*/
5632
5633static void PrettyCommentFactor (pge_FactorDesc f, unsigned int Left)
5634{
5635 unsigned int curpos;
5636 unsigned int seentext;
5637
5638 while (f != NULL)
5639 {
5640 CheckNewLine (Left);
5641 switch (f->type)
5642 {
5643 case pge_id:
5644 Output_WriteKey (f->ident->name);
5645 Output_WriteString ((const char *) " ", 1);
5646 Indent += (NameKey_LengthKey (f->ident->name))+1;
5647 break;
5648
5649 case pge_lit:
5650 if ((NameKey_MakeKey ((const char *) "'", 1)) == f->string)
5651 {
5652 Output_Write ('"');
5653 WriteKeyTexinfo (f->string);
5654 Output_WriteString ((const char *) "\" ", 2);
5655 }
5656 else
5657 {
5658 Output_Write ('\'');
5659 WriteKeyTexinfo (f->string);
5660 Output_WriteString ((const char *) "' ", 2);
5661 }
5662 Indent += (NameKey_LengthKey (f->string))+3;
5663 break;
5664
5665 case pge_sub:
5666 PrettyPara ((const char *) "( ", 2, (const char *) " ) ", 3, f->expr, Left);
5667 break;
5668
5669 case pge_opt:
5670 PrettyPara ((const char *) "[ ", 2, (const char *) " ] ", 3, f->expr, Left);
5671 break;
5672
5673 case pge_mult:
5674 if (Texinfo)
5675 {
5676 PrettyPara ((const char *) "@{ ", 3, (const char *) " @} ", 4, f->expr, Left);
5677 }
5678 else
5679 {
5680 PrettyPara ((const char *) "{ ", 2, (const char *) " } ", 3, f->expr, Left);
5681 }
5682 break;
5683
5684 case pge_m2:
5685 if (EmitCode)
5686 {
5687 NewLine (Left);
5688 Output_WriteString ((const char *) "% ", 2);
5689 seentext = FALSE;
5690 curpos = 0;
5691 WriteCodeHunkListIndent (f->code->code, f->code->indent, &curpos, Left+2, &seentext);
5692 Output_WriteString ((const char *) " %", 2);
5693 NewLine (Left);
5694 }
5695 break;
5696
5697
5698 default:
5699 break;
5700 }
5701 PrettyFollow ((const char *) "<f:", 3, (const char *) ":f>", 3, f->followinfo);
5702 f = f->next;
5703 }
5704}
5705
5706
5707/*
5708 PeepTerm - returns the length of characters in term.
5709*/
5710
5711static unsigned int PeepTerm (pge_TermDesc t)
5712{
5713 unsigned int l;
5714
5715 l = 0;
5716 while (t != NULL)
5717 {
5718 l += PeepFactor (t->factor);
5719 if (t->next != NULL)
5720 {
5721 l += 3;
5722 }
5723 t = t->next;
5724 }
5725 return l;
5726 /* static analysis guarentees a RETURN statement will be used before here. */
5727 __builtin_unreachable ();
5728}
5729
5730
5731/*
5732 PeepExpression - returns the length of the expression.
5733*/
5734
5735static unsigned int PeepExpression (pge_ExpressionDesc e)
5736{
5737 if (e == NULL)
5738 {
5739 return 0;
5740 }
5741 else
5742 {
5743 return PeepTerm (e->term);
5744 }
5745 /* static analysis guarentees a RETURN statement will be used before here. */
5746 __builtin_unreachable ();
5747}
5748
5749
5750/*
5751 PeepFactor - returns the length of character in the factor
5752*/
5753
5754static unsigned int PeepFactor (pge_FactorDesc f)
5755{
5756 unsigned int l;
5757
5758 l = 0;
5759 while (f != NULL)
5760 {
5761 switch (f->type)
5762 {
5763 case pge_id:
5764 l += (NameKey_LengthKey (f->ident->name))+1;
5765 break;
5766
5767 case pge_lit:
5768 l += (NameKey_LengthKey (f->string))+3;
5769 break;
5770
5771 case pge_opt:
5772 case pge_mult:
5773 case pge_sub:
5774 l += PeepExpression (f->expr);
5775 break;
5776
5777 case pge_m2:
5778 break;
5779
5780
5781 default:
5782 break;
5783 }
5784 f = f->next; /* empty */
5785 }
5786 return l;
5787 /* static analysis guarentees a RETURN statement will be used before here. */
5788 __builtin_unreachable ();
5789}
5790
5791
5792/*
5793 PrettyCommentTerm -
5794*/
5795
5796static void PrettyCommentTerm (pge_TermDesc t, unsigned int Left)
5797{
5798 while (t != NULL)
5799 {
5800 CheckNewLine (Left);
5801 PrettyCommentFactor (t->factor, Left);
5802 if (t->next != NULL)
5803 {
5804 Output_WriteString ((const char *) " | ", 3);
5805 Indent += 3;
5806 if (((PeepFactor (t->factor))+Indent) > BaseRightMargin)
5807 {
5808 NewLine (Left);
5809 }
5810 }
5811 PrettyFollow ((const char *) "<t:", 3, (const char *) ":t>", 3, t->followinfo);
5812 t = t->next;
5813 }
5814}
5815
5816
5817/*
5818 PrettyCommentExpression -
5819*/
5820
5821static void PrettyCommentExpression (pge_ExpressionDesc e, unsigned int Left)
5822{
5823 if (e != NULL)
5824 {
5825 PrettyCommentTerm (e->term, Left);
5826 PrettyFollow ((const char *) "<e:", 3, (const char *) ":e>", 3, e->followinfo);
5827 }
5828}
5829
5830
5831/*
5832 PrettyCommentStatement -
5833*/
5834
5835static void PrettyCommentStatement (pge_StatementDesc s, unsigned int Left)
5836{
5837 if (s != NULL)
5838 {
5839 PrettyCommentExpression (s->expr, Left);
5840 PrettyFollow ((const char *) "<s:", 3, (const char *) ":s>", 3, s->followinfo);
5841 }
5842}
5843
5844
5845/*
5846 PrettyCommentProduction - generates the comment for rule, p.
5847*/
5848
5849static void PrettyCommentProduction (pge_ProductionDesc p)
5850{
5851 pge_SetDesc to;
5852
5853 if (p != NULL)
5854 {
5855 BeginningOfLine = TRUE;
5856 Indent = 0;
5857 Output_WriteString ((const char *) "(*", 2);
5858 NewLine (3);
5859 Output_WriteKey (GetDefinitionName (p));
5860 Output_WriteString ((const char *) " := ", 4);
5861 Indent += (NameKey_LengthKey (GetDefinitionName (p)))+4;
5862 PrettyCommentStatement (p->statement, Indent);
5863 NewLine (0);
5864 if (ErrorRecovery)
5865 {
5866 NewLine (3);
5867 Output_WriteString ((const char *) "first symbols:", 15);
5868 EmitSet (p->first, static_cast<unsigned int> (0), static_cast<unsigned int> (0));
5869 NewLine (3);
5870 PrettyFollow ((const char *) "<p:", 3, (const char *) ":p>", 3, p->followinfo);
5871 NewLine (3);
5872 switch (GetReachEnd (p->followinfo))
5873 {
5874 case pge_true:
5875 Output_WriteString ((const char *) "reachend", 8);
5876 break;
5877
5878 case pge_false:
5879 Output_WriteString ((const char *) "cannot reachend", 15);
5880 break;
5881
5882 case pge_unknown:
5883 Output_WriteString ((const char *) "unknown...", 10);
5884 break;
5885
5886
5887 default:
5888 break;
5889 }
5890 NewLine (0);
5891 }
5892 Output_WriteString ((const char *) "*)", 2);
5893 NewLine (0);
5894 }
5895}
5896
5897
5898/*
5899 PrettyPrintProduction - pretty prints the ebnf rule, p.
5900*/
5901
5902static void PrettyPrintProduction (pge_ProductionDesc p)
5903{
5904 pge_SetDesc to;
5905
5906 if (p != NULL)
5907 {
5908 BeginningOfLine = TRUE;
5909 Indent = 0;
5910 if (Texinfo)
5911 {
5912 Output_WriteString ((const char *) "@example", 8);
5913 NewLine (0);
5914 }
5915 else if (Sphinx)
5916 {
5917 /* avoid dangling else. */
5918 Output_WriteString ((const char *) ".. code-block:: ebnf", 20);
5919 NewLine (0);
5920 }
5921 Output_WriteKey (GetDefinitionName (p));
5922 Output_WriteString ((const char *) " := ", 4);
5923 Indent += (NameKey_LengthKey (GetDefinitionName (p)))+4;
5924 PrettyCommentStatement (p->statement, Indent);
5925 if (p->description != NameKey_NulName)
5926 {
5927 Output_WriteKey (p->description);
5928 }
5929 NewLine (0);
5930 WriteIndent ((NameKey_LengthKey (GetDefinitionName (p)))+1);
5931 Output_WriteString ((const char *) " =: ", 4);
5932 NewLine (0);
5933 if (Texinfo)
5934 {
5935 Output_WriteString ((const char *) "@findex ", 8);
5936 Output_WriteKey (GetDefinitionName (p));
5937 Output_WriteString ((const char *) " (ebnf)", 7);
5938 NewLine (0);
5939 Output_WriteString ((const char *) "@end example", 12);
5940 NewLine (0);
5941 }
5942 else if (Sphinx)
5943 {
5944 /* avoid dangling else. */
5945 Output_WriteString ((const char *) ".. index::", 10);
5946 NewLine (0);
5947 Output_WriteString ((const char *) " pair: ", 8);
5948 Output_WriteKey (GetDefinitionName (p));
5949 Output_WriteString ((const char *) "; (ebnf)", 8);
5950 NewLine (0);
5951 }
5952 NewLine (0);
5953 }
5954}
5955
5956
5957/*
5958 EmitFileLineTag - emits a line and file tag using the C preprocessor syntax.
5959*/
5960
5961static void EmitFileLineTag (unsigned int line)
5962{
5963 if (! SuppressFileLineTag && (line != LastLineNo))
5964 {
5965 LastLineNo = line;
5966 if (! OnLineStart)
5967 {
5968 Output_WriteLn ();
5969 }
5970 Output_WriteString ((const char *) "# ", 2);
5971 Output_WriteCard (line, 0);
5972 Output_WriteString ((const char *) " \"", 2);
5973 Output_WriteString ((const char *) &FileName.array[0], MaxFileName);
5974 Output_Write ('"');
5975 Output_WriteLn ();
5976 OnLineStart = TRUE;
5977 }
5978}
5979
5980
5981/*
5982 EmitRule - generates a comment and code for rule, p.
5983*/
5984
5985static void EmitRule (pge_ProductionDesc p)
5986{
5987 if (PrettyPrint)
5988 {
5989 PrettyPrintProduction (p);
5990 }
5991 else
5992 {
5993 PrettyCommentProduction (p);
5994 if (ErrorRecovery)
5995 {
5996 RecoverProduction (p);
5997 }
5998 else
5999 {
6000 CodeProduction (p);
6001 }
6002 }
6003}
6004
6005
6006/*
6007 CodeCondition -
6008*/
6009
6010static void CodeCondition (pge_m2condition m)
6011{
6012 switch (m)
6013 {
6014 case pge_m2if:
6015 case pge_m2none:
6016 IndentString ((const char *) "IF ", 3);
6017 break;
6018
6019 case pge_m2elsif:
6020 IndentString ((const char *) "ELSIF ", 6);
6021 break;
6022
6023 case pge_m2while:
6024 IndentString ((const char *) "WHILE ", 6);
6025 break;
6026
6027
6028 default:
6029 Debug_Halt ((const char *) "unrecognised m2condition", 24, 2680, (const char *) "m2/gm2-auto/pge.mod", 19);
6030 break;
6031 }
6032}
6033
6034
6035/*
6036 CodeThenDo - codes a "THEN" or "DO" depending upon, m.
6037*/
6038
6039static void CodeThenDo (pge_m2condition m)
6040{
6041 switch (m)
6042 {
6043 case pge_m2if:
6044 case pge_m2none:
6045 case pge_m2elsif:
6046 if (LastLineNo == 0)
6047 {
6048 Output_WriteLn ();
6049 }
6050 IndentString ((const char *) "THEN", 4);
6051 Output_WriteLn ();
6052 break;
6053
6054 case pge_m2while:
6055 Output_WriteString ((const char *) " DO", 3);
6056 Output_WriteLn ();
6057 break;
6058
6059
6060 default:
6061 Debug_Halt ((const char *) "unrecognised m2condition", 24, 2705, (const char *) "m2/gm2-auto/pge.mod", 19);
6062 break;
6063 }
6064 OnLineStart = TRUE;
6065}
6066
6067
6068/*
6069 CodeElseEnd - builds an ELSE END statement using string, end.
6070*/
6071
6072static void CodeElseEnd (const char *end_, unsigned int _end_high, unsigned int consumed, pge_FactorDesc f, unsigned int inopt)
6073{
6074 char end[_end_high+1];
6075
6076 /* make a local copy of each unbounded array. */
6077 memcpy (end, end_, _end_high+1);
6078
6079 Output_WriteLn ();
6080 OnLineStart = TRUE;
6081 EmitFileLineTag (f->line);
6082 if (! inopt)
6083 {
6084 IndentString ((const char *) "ELSE", 4);
6085 StrIO_WriteLn ();
6086 Indent += 3;
6087 if (consumed)
6088 {
6089 IndentString ((const char *) "", 0);
6090 Output_WriteKey (ErrorProcArray);
6091 Output_Write ('(');
6092 switch (f->type)
6093 {
6094 case pge_id:
6095 Output_Write ('\'');
6096 Output_WriteKey (f->ident->name);
6097 Output_WriteString ((const char *) " - expected", 11);
6098 Output_WriteString ((const char *) "') ;", 4);
6099 break;
6100
6101 case pge_lit:
6102 if ((NameKey_MakeKey ((const char *) "'", 1)) == f->string)
6103 {
6104 Output_Write ('"');
6105 KeyWord (f->string);
6106 Output_WriteString ((const char *) " - expected", 11);
6107 Output_WriteString ((const char *) "\") ;", 4);
6108 }
6109 else if ((NameKey_MakeKey ((const char *) "\"", 1)) == f->string)
6110 {
6111 /* avoid dangling else. */
6112 Output_Write ('\'');
6113 KeyWord (f->string);
6114 Output_WriteString ((const char *) " - expected", 11);
6115 Output_WriteString ((const char *) "') ;", 4);
6116 }
6117 else
6118 {
6119 /* avoid dangling else. */
6120 Output_Write ('"');
6121 Output_Write ('\'');
6122 KeyWord (f->string);
6123 Output_WriteString ((const char *) "' - expected", 12);
6124 Output_WriteString ((const char *) "\") ;", 4);
6125 }
6126 break;
6127
6128
6129 default:
6130 break;
6131 }
6132 Output_WriteLn ();
6133 }
6134 IndentString ((const char *) "RETURN( FALSE )", 15);
6135 Indent -= 3;
6136 Output_WriteLn ();
6137 }
6138 IndentString ((const char *) end, _end_high);
6139 Output_WriteLn ();
6140 OnLineStart = TRUE;
6141}
6142
6143
6144/*
6145 CodeEnd - codes a "END" depending upon, m.
6146*/
6147
6148static void CodeEnd (pge_m2condition m, pge_TermDesc t, unsigned int consumed, pge_FactorDesc f, unsigned int inopt)
6149{
6150 Indent -= 3;
6151 Output_WriteLn ();
6152 OnLineStart = TRUE;
6153 switch (m)
6154 {
6155 case pge_m2none:
6156 if (t == NULL)
6157 {
6158 CodeElseEnd ((const char *) "END ;", 5, consumed, f, inopt);
6159 }
6160 break;
6161
6162 case pge_m2if:
6163 if (t == NULL)
6164 {
6165 CodeElseEnd ((const char *) "END ; (* if *)", 15, consumed, f, inopt);
6166 }
6167 break;
6168
6169 case pge_m2elsif:
6170 if (t == NULL)
6171 {
6172 CodeElseEnd ((const char *) "END ; (* elsif *)", 18, consumed, f, inopt);
6173 }
6174 break;
6175
6176 case pge_m2while:
6177 IndentString ((const char *) "END ; (* while *)", 18);
6178 break;
6179
6180
6181 default:
6182 Debug_Halt ((const char *) "unrecognised m2condition", 24, 2788, (const char *) "m2/gm2-auto/pge.mod", 19);
6183 break;
6184 }
6185 OnLineStart = FALSE;
6186}
6187
6188
6189/*
6190 EmitNonVarCode - writes out, code, providing it is not a variable declaration.
6191*/
6192
6193static void EmitNonVarCode (pge_CodeDesc code, unsigned int curpos, unsigned int left)
6194{
6195 unsigned int i;
6196 pge_CodeHunk t;
6197 unsigned int seentext;
6198
6199 t = code->code;
6200 if ((! (FindStr (&t, &i, (const char *) "VAR", 3))) && EmitCode)
6201 {
6202 seentext = FALSE;
6203 curpos = 0;
6204 EmitFileLineTag (code->line);
6205 IndentString ((const char *) "", 0);
6206 WriteCodeHunkListIndent (code->code, code->indent, &curpos, left, &seentext);
6207 Output_WriteString ((const char *) " ;", 2);
6208 Output_WriteLn ();
6209 OnLineStart = TRUE;
6210 }
6211}
6212
6213
6214/*
6215 ChainOn -
6216*/
6217
6218static pge_FactorDesc ChainOn (pge_FactorDesc codeStack, pge_FactorDesc f)
6219{
6220 pge_FactorDesc s;
6221
6222 f->pushed = NULL;
6223 if (codeStack == NULL)
6224 {
6225 return f;
6226 }
6227 else
6228 {
6229 s = codeStack;
6230 while (s->pushed != NULL)
6231 {
6232 s = s->pushed;
6233 }
6234 s->pushed = f;
6235 return codeStack;
6236 }
6237 /* static analysis guarentees a RETURN statement will be used before here. */
6238 __builtin_unreachable ();
6239}
6240
6241
6242/*
6243 FlushCode -
6244*/
6245
6246static void FlushCode (pge_FactorDesc *codeStack)
6247{
6248 if ((*codeStack) != NULL)
6249 {
6250 NewLine (Indent);
6251 Output_WriteString ((const char *) "(* begin flushing code *)", 25);
6252 OnLineStart = FALSE;
6253 while ((*codeStack) != NULL)
6254 {
6255 NewLine (Indent);
6256 EmitNonVarCode ((*codeStack)->code, 0, Indent);
6257 NewLine (Indent);
6258 (*codeStack) = (*codeStack)->pushed;
6259 if ((*codeStack) != NULL)
6260 {
6261 Output_WriteString ((const char *) " (* again flushing code *)", 26);
6262 Output_WriteLn ();
6263 OnLineStart = TRUE;
6264 }
6265 }
6266 NewLine (Indent);
6267 Output_WriteString ((const char *) "(* end flushing code *)", 23);
6268 OnLineStart = FALSE;
6269 }
6270}
6271
6272
6273/*
6274 CodeFactor -
6275*/
6276
6277static void CodeFactor (pge_FactorDesc f, pge_TermDesc t, pge_m2condition l, pge_m2condition n, unsigned int inopt, unsigned int inwhile, unsigned int consumed, pge_FactorDesc codeStack)
6278{
6279 if (f == NULL)
6280 {
6281 /* avoid dangling else. */
6282 if (! inwhile && ! inopt) /* ((l=m2elsif) OR (l=m2if) OR (l=m2none)) AND */
6283 {
6284 Output_WriteLn ();
6285 IndentString ((const char *) "RETURN( TRUE )", 14);
6286 OnLineStart = FALSE;
6287 }
6288 }
6289 else
6290 {
6291 EmitFileLineTag (f->line);
6292 switch (f->type)
6293 {
6294 case pge_id:
6295 FlushCode (&codeStack);
6296 CodeCondition (n);
6297 Output_WriteKey (f->ident->name);
6298 Output_WriteString ((const char *) "()", 2);
6299 CodeThenDo (n);
6300 Indent += 3;
6301 CodeFactor (f->next, NULL, n, pge_m2none, inopt, inwhile, TRUE, NULL);
6302 CodeEnd (n, t, consumed, f, inopt);
6303 break;
6304
6305 case pge_lit:
6306 FlushCode (&codeStack);
6307 CodeCondition (n);
6308 Output_WriteKey (SymIsProc);
6309 Output_Write ('(');
6310 Output_WriteKey (SymbolKey_GetSymKey (Aliases, f->string));
6311 Output_Write (')');
6312 CodeThenDo (n);
6313 Indent += 3;
6314 CodeFactor (f->next, NULL, n, pge_m2none, inopt, inwhile, TRUE, NULL);
6315 CodeEnd (n, t, consumed, f, inopt);
6316 break;
6317
6318 case pge_sub:
6319 FlushCode (&codeStack);
6320 CodeExpression (f->expr, pge_m2none, inopt, inwhile, consumed, NULL);
6321 if (f->next != NULL)
6322 {
6323 /*
6324 * the test above makes sure that we don't emit a RETURN( TRUE )
6325 * after a subexpression. Remember sub expressions are not conditional
6326 */
6327 CodeFactor (f->next, t, n, pge_m2none, inopt, inwhile, TRUE, NULL);
6328 }
6329 break;
6330
6331 case pge_opt:
6332 FlushCode (&codeStack);
6333 CodeExpression (f->expr, pge_m2if, TRUE, inwhile, FALSE, NULL);
6334 CodeFactor (f->next, t, n, pge_m2none, inopt, inwhile, consumed, NULL);
6335 break;
6336
6337 case pge_mult:
6338 FlushCode (&codeStack);
6339 CodeExpression (f->expr, pge_m2while, FALSE, TRUE, consumed, NULL);
6340 CodeFactor (f->next, t, n, pge_m2none, inopt, inwhile, consumed, NULL);
6341 break;
6342
6343 case pge_m2:
6344 codeStack = ChainOn (codeStack, f);
6345 if (consumed || (f->next == NULL))
6346 {
6347 FlushCode (&codeStack);
6348 }
6349 CodeFactor (f->next, t, n, pge_m2none, inopt, inwhile, consumed, codeStack);
6350 break;
6351
6352
6353 default:
6354 break;
6355 }
6356 }
6357}
6358
6359
6360/*
6361 CodeTerm -
6362*/
6363
6364static void CodeTerm (pge_TermDesc t, pge_m2condition m, unsigned int inopt, unsigned int inwhile, unsigned int consumed, pge_FactorDesc codeStack)
6365{
6366 pge_m2condition l;
6367
6368 l = m;
6369 while (t != NULL)
6370 {
6371 EmitFileLineTag (t->line);
6372 if ((t->factor->type == pge_m2) && (m == pge_m2elsif))
6373 {
6374 m = pge_m2if;
6375 IndentString ((const char *) "ELSE", 4);
6376 Output_WriteLn ();
6377 OnLineStart = TRUE;
6378 Indent += 3;
6379 CodeFactor (t->factor, t->next, pge_m2none, pge_m2none, inopt, inwhile, consumed, codeStack);
6380 Indent -= 3;
6381 IndentString ((const char *) "END ;", 5);
6382 Output_WriteLn ();
6383 OnLineStart = TRUE;
6384 }
6385 else
6386 {
6387 CodeFactor (t->factor, t->next, pge_m2none, m, inopt, inwhile, consumed, codeStack);
6388 }
6389 l = m;
6390 if (t->next != NULL)
6391 {
6392 m = pge_m2elsif;
6393 }
6394 t = t->next;
6395 }
6396}
6397
6398
6399/*
6400 CodeExpression -
6401*/
6402
6403static void CodeExpression (pge_ExpressionDesc e, pge_m2condition m, unsigned int inopt, unsigned int inwhile, unsigned int consumed, pge_FactorDesc codeStack)
6404{
6405 if (e != NULL)
6406 {
6407 EmitFileLineTag (e->line);
6408 CodeTerm (e->term, m, inopt, inwhile, consumed, codeStack);
6409 }
6410}
6411
6412
6413/*
6414 CodeStatement -
6415*/
6416
6417static void CodeStatement (pge_StatementDesc s, pge_m2condition m)
6418{
6419 if (s != NULL)
6420 {
6421 EmitFileLineTag (s->line);
6422 CodeExpression (s->expr, m, FALSE, FALSE, FALSE, NULL);
6423 }
6424}
6425
6426
6427/*
6428 CodeProduction - only encode grammer rules which are not special.
6429*/
6430
6431static void CodeProduction (pge_ProductionDesc p)
6432{
6433 if ((p != NULL) && (! p->firstsolved || ((p->statement != NULL) && (p->statement->expr != NULL))))
6434 {
6435 BeginningOfLine = TRUE;
6436 Indent = 0;
6437 Output_WriteLn ();
6438 EmitFileLineTag (p->line);
6439 IndentString ((const char *) "PROCEDURE ", 10);
6440 Output_WriteKey (GetDefinitionName (p));
6441 Output_WriteString ((const char *) " () : BOOLEAN ;", 15);
6442 VarProduction (p);
6443 Output_WriteLn ();
6444 OnLineStart = TRUE;
6445 EmitFileLineTag (p->line);
6446 IndentString ((const char *) "BEGIN", 5);
6447 StrIO_WriteLn ();
6448 OnLineStart = FALSE;
6449 EmitFileLineTag (p->line);
6450 Indent = 3;
6451 CodeStatement (p->statement, pge_m2none);
6452 Output_WriteLn ();
6453 Indent = 0;
6454 IndentString ((const char *) "END ", 4);
6455 NameKey_WriteKey (GetDefinitionName (p));
6456 Output_WriteString ((const char *) " ;", 2);
6457 Output_WriteLn ();
6458 Output_WriteLn ();
6459 Output_WriteLn ();
6460 }
6461}
6462
6463
6464/*
6465 RecoverCondition -
6466*/
6467
6468static void RecoverCondition (pge_m2condition m)
6469{
6470 switch (m)
6471 {
6472 case pge_m2if:
6473 IndentString ((const char *) "IF ", 3);
6474 break;
6475
6476 case pge_m2none:
6477 IndentString ((const char *) "IF ", 3);
6478 break;
6479
6480 case pge_m2elsif:
6481 IndentString ((const char *) "ELSIF ", 6);
6482 break;
6483
6484 case pge_m2while:
6485 IndentString ((const char *) "WHILE ", 6);
6486 break;
6487
6488
6489 default:
6490 Debug_Halt ((const char *) "unrecognised m2condition", 24, 3045, (const char *) "m2/gm2-auto/pge.mod", 19);
6491 break;
6492 }
6493}
6494
6495
6496/*
6497 ConditionIndent - returns the number of spaces indentation created via, m.
6498*/
6499
6500static unsigned int ConditionIndent (pge_m2condition m)
6501{
6502 switch (m)
6503 {
6504 case pge_m2if:
6505 return 3;
6506 break;
6507
6508 case pge_m2none:
6509 return 3;
6510 break;
6511
6512 case pge_m2elsif:
6513 return 6;
6514 break;
6515
6516 case pge_m2while:
6517 return 6;
6518 break;
6519
6520
6521 default:
6522 Debug_Halt ((const char *) "unrecognised m2condition", 24, 3064, (const char *) "m2/gm2-auto/pge.mod", 19);
6523 break;
6524 }
6525 ReturnException ("m2/gm2-auto/pge.mod", 1, 7);
6526 __builtin_unreachable ();
6527}
6528
6529
6530/*
6531 WriteGetTokenType - writes out the method of determining the token type.
6532*/
6533
6534static void WriteGetTokenType (void)
6535{
6536 Output_WriteKey (TokenTypeProc);
6537}
6538
6539
6540/*
6541 NumberOfElements - returns the number of elements in set, to, which lie between low..high
6542*/
6543
6544static unsigned int NumberOfElements (pge_SetDesc to, unsigned int low, unsigned int high)
6545{
6546 unsigned int n;
6547
6548 n = 0;
6549 while (to != NULL)
6550 {
6551 switch (to->type)
6552 {
6553 case pge_tokel:
6554 if ((high == 0) || (IsBetween (to->string, low, high)))
6555 {
6556 n += 1;
6557 }
6558 break;
6559
6560 case pge_litel:
6561 if ((high == 0) || (IsBetween (SymbolKey_GetSymKey (Aliases, to->string), low, high)))
6562 {
6563 n += 1;
6564 }
6565 break;
6566
6567 case pge_idel:
6568 PushBackInput_WarnError ((const char *) "not expecting ident in first symbol list", 40);
6569 WasNoError = FALSE;
6570 break;
6571
6572
6573 default:
6574 PushBackInput_WarnError ((const char *) "unknown enuneration element", 27);
6575 WasNoError = FALSE;
6576 break;
6577 }
6578 to = to->next;
6579 }
6580 return n;
6581 /* static analysis guarentees a RETURN statement will be used before here. */
6582 __builtin_unreachable ();
6583}
6584
6585
6586/*
6587 WriteElement - writes the literal name for element, e.
6588*/
6589
6590static void WriteElement (unsigned int e)
6591{
6592 Output_WriteKey (SymbolKey_GetSymKey (ReverseValues, e));
6593}
6594
6595
6596/*
6597 EmitIsInSet - writes out the equivalent of GetTokenType() IN { toset }
6598*/
6599
6600static void EmitIsInSet (pge_SetDesc to, NameKey_Name low, NameKey_Name high)
6601{
6602 if ((NumberOfElements (to, low, high)) == 1)
6603 {
6604 WriteGetTokenType ();
6605 Output_Write ('=');
6606 EmitSet (to, low, high);
6607 }
6608 else
6609 {
6610 WriteGetTokenType ();
6611 Output_WriteString ((const char *) " IN SetOfStop", 13);
6612 if (LargestValue > MaxElementsInSet)
6613 {
6614 Output_WriteCard (((unsigned int ) (low)) / MaxElementsInSet, 0);
6615 }
6616 Output_WriteString ((const char *) " {", 2);
6617 EmitSet (to, low, high);
6618 Output_WriteString ((const char *) "}", 1);
6619 }
6620}
6621
6622
6623/*
6624 EmitIsInSubSet - writes out a test to see whether GetTokenype() is in { subset }
6625*/
6626
6627static void EmitIsInSubSet (pge_SetDesc to, unsigned int low, unsigned int high)
6628{
6629 if ((NumberOfElements (to, low, high)) == 1)
6630 {
6631 Output_Write ('(');
6632 EmitIsInSet (to, low, high);
6633 Output_Write (')');
6634 }
6635 else if (low == 0)
6636 {
6637 /* avoid dangling else. */
6638 /* no need to check whether GetTokenType > low */
6639 Output_WriteString ((const char *) "((", 2);
6640 WriteGetTokenType ();
6641 Output_Write ('<');
6642 WriteElement (static_cast<unsigned int> (((int ) (high))+1));
6643 Output_WriteString ((const char *) ") AND (", 7);
6644 EmitIsInSet (to, low, high);
6645 Output_WriteString ((const char *) "))", 2);
6646 }
6647 else if (((unsigned int ) (high)) > LargestValue)
6648 {
6649 /* avoid dangling else. */
6650 /* no need to check whether GetTokenType < high */
6651 Output_WriteString ((const char *) "((", 2);
6652 WriteGetTokenType ();
6653 Output_WriteString ((const char *) ">=", 2);
6654 WriteElement (low);
6655 Output_WriteString ((const char *) ") AND (", 7);
6656 EmitIsInSet (to, low, high);
6657 Output_WriteString ((const char *) "))", 2);
6658 }
6659 else
6660 {
6661 /* avoid dangling else. */
6662 Output_WriteString ((const char *) "((", 2);
6663 WriteGetTokenType ();
6664 Output_WriteString ((const char *) ">=", 2);
6665 WriteElement (low);
6666 Output_WriteString ((const char *) ") AND (", 7);
6667 WriteGetTokenType ();
6668 Output_Write ('<');
6669 WriteElement (static_cast<unsigned int> (((int ) (high))+1));
6670 Output_WriteString ((const char *) ") AND (", 7);
6671 EmitIsInSet (to, low, high);
6672 Output_WriteString ((const char *) "))", 2);
6673 }
6674}
6675
6676
6677/*
6678 EmitIsInFirst -
6679*/
6680
6681static void EmitIsInFirst (pge_SetDesc to, pge_m2condition m)
6682{
6683 unsigned int i;
6684 unsigned int first;
6685
6686 if ((NumberOfElements (to, static_cast<unsigned int> (0), static_cast<unsigned int> (0))) == 1)
6687 {
6688 /* only one element */
6689 WriteGetTokenType ();
6690 Output_Write ('=');
6691 EmitSet (to, static_cast<unsigned int> (0), static_cast<unsigned int> (0));
6692 }
6693 else
6694 {
6695 if (LargestValue <= MaxElementsInSet)
6696 {
6697 Output_Write ('(');
6698 WriteGetTokenType ();
6699 Output_WriteString ((const char *) " IN ", 4);
6700 EmitSetAsParameters (to);
6701 Output_WriteString ((const char *) ")", 1);
6702 }
6703 else
6704 {
6705 i = 0;
6706 first = TRUE;
6707 do {
6708 if (! (IsEmptySet (to, i*MaxElementsInSet, ((i+1)*MaxElementsInSet)-1)))
6709 {
6710 if (! first)
6711 {
6712 Output_WriteString ((const char *) " OR", 3);
6713 NewLine (Indent+(ConditionIndent (m)));
6714 Indent -= ConditionIndent (m);
6715 }
6716 EmitIsInSubSet (to, i*MaxElementsInSet, ((i+1)*MaxElementsInSet)-1);
6717 first = FALSE;
6718 }
6719 i += 1;
6720 } while (! ((i*MaxElementsInSet) > LargestValue));
6721 }
6722 }
6723}
6724
6725static void FlushRecoverCode (pge_FactorDesc *codeStack)
6726{
6727 /*
6728 FlushCode -
6729 */
6730 if ((*codeStack) != NULL)
6731 {
6732 while ((*codeStack) != NULL)
6733 {
6734 EmitNonVarCode ((*codeStack)->code, 0, Indent);
6735 (*codeStack) = (*codeStack)->pushed;
6736 }
6737 }
6738}
6739
6740
6741/*
6742 RecoverFactor -
6743*/
6744
6745static void RecoverFactor (pge_FactorDesc f, pge_m2condition m, pge_FactorDesc codeStack)
6746{
6747 pge_SetDesc to;
6748
6749 if (f == NULL)
6750 {} /* empty. */
6751 else
6752 {
6753 EmitFileLineTag (f->line);
6754 switch (f->type)
6755 {
6756 case pge_id:
6757 to = NULL;
6758 CalcFirstFactor (f, NULL, &to);
6759 if ((to != NULL) && (m != pge_m2none))
6760 {
6761 RecoverCondition (m);
6762 EmitIsInFirst (to, m);
6763 CodeThenDo (m);
6764 Indent += 3;
6765 }
6766 FlushRecoverCode (&codeStack);
6767 IndentString ((const char *) "", 0);
6768 Output_WriteKey (f->ident->name);
6769 Output_Write ('(');
6770 EmitStopParametersAndFollow (f, m);
6771 Output_WriteString ((const char *) ") ;", 3);
6772 Output_WriteLn ();
6773 RecoverFactor (f->next, pge_m2none, codeStack);
6774 if ((to != NULL) && (m != pge_m2none))
6775 {
6776 Indent -= 3;
6777 }
6778 break;
6779
6780 case pge_lit:
6781 if (m == pge_m2none)
6782 {
6783 FlushRecoverCode (&codeStack);
6784 IndentString ((const char *) "Expect(", 7);
6785 Output_WriteKey (SymbolKey_GetSymKey (Aliases, f->string));
6786 Output_WriteString ((const char *) ", ", 2);
6787 EmitStopParametersAndFollow (f, m);
6788 Output_WriteString ((const char *) ") ;", 3);
6789 Output_WriteLn ();
6790 RecoverFactor (f->next, pge_m2none, codeStack);
6791 }
6792 else
6793 {
6794 RecoverCondition (m);
6795 WriteGetTokenType ();
6796 Output_Write ('=');
6797 Output_WriteKey (SymbolKey_GetSymKey (Aliases, f->string));
6798 CodeThenDo (m);
6799 Indent += 3;
6800 IndentString ((const char *) "Expect(", 7);
6801 Output_WriteKey (SymbolKey_GetSymKey (Aliases, f->string));
6802 Output_WriteString ((const char *) ", ", 2);
6803 EmitStopParametersAndFollow (f, m);
6804 Output_WriteString ((const char *) ") ;", 3);
6805 Output_WriteLn ();
6806 FlushRecoverCode (&codeStack);
6807 RecoverFactor (f->next, pge_m2none, codeStack);
6808 Indent -= 3;
6809 }
6810 break;
6811
6812 case pge_sub:
6813 FlushRecoverCode (&codeStack);
6814 RecoverExpression (f->expr, pge_m2none, m);
6815 RecoverFactor (f->next, pge_m2none, codeStack);
6816 break;
6817
6818 case pge_opt:
6819 FlushRecoverCode (&codeStack);
6820 if (OptExpSeen (f))
6821 {
6822 to = NULL;
6823 CalcFirstExpression (f->expr, NULL, &to);
6824 RecoverCondition (m);
6825 EmitIsInFirst (to, m);
6826 CodeThenDo (m);
6827 Indent += 3;
6828 IndentString ((const char *) "(* seen optional [ | ] expression *)", 36);
6829 Output_WriteLn ();
6830 stop ();
6831 RecoverExpression (f->expr, pge_m2none, pge_m2if);
6832 IndentString ((const char *) "(* end of optional [ | ] expression *)", 38);
6833 Output_WriteLn ();
6834 Indent -= 3;
6835 IndentString ((const char *) "END ;", 5);
6836 Output_WriteLn ();
6837 }
6838 else
6839 {
6840 RecoverExpression (f->expr, pge_m2if, m);
6841 }
6842 RecoverFactor (f->next, pge_m2none, codeStack);
6843 break;
6844
6845 case pge_mult:
6846 FlushRecoverCode (&codeStack);
6847 if (((OptExpSeen (f)) || (m == pge_m2if)) || (m == pge_m2elsif))
6848 {
6849 /* avoid dangling else. */
6850 to = NULL;
6851 CalcFirstExpression (f->expr, NULL, &to);
6852 RecoverCondition (m);
6853 EmitIsInFirst (to, m);
6854 CodeThenDo (m);
6855 Indent += 3;
6856 IndentString ((const char *) "(* seen optional { | } expression *)", 36);
6857 Output_WriteLn ();
6858 RecoverCondition (pge_m2while);
6859 EmitIsInFirst (to, pge_m2while);
6860 CodeThenDo (pge_m2while);
6861 Indent += 3;
6862 RecoverExpression (f->expr, pge_m2none, pge_m2while);
6863 IndentString ((const char *) "(* end of optional { | } expression *)", 38);
6864 Output_WriteLn ();
6865 Indent -= 3;
6866 IndentString ((const char *) "END ;", 5);
6867 Output_WriteLn ();
6868 Indent -= 3;
6869 if (m == pge_m2none)
6870 {
6871 IndentString ((const char *) "END ;", 5);
6872 Output_WriteLn ();
6873 Indent -= 3;
6874 }
6875 }
6876 else
6877 {
6878 RecoverExpression (f->expr, pge_m2while, m);
6879 }
6880 RecoverFactor (f->next, pge_m2none, codeStack);
6881 break;
6882
6883 case pge_m2:
6884 codeStack = ChainOn (codeStack, f);
6885 if (f->next == NULL)
6886 {
6887 FlushRecoverCode (&codeStack);
6888 }
6889 else
6890 {
6891 RecoverFactor (f->next, m, codeStack); /* was m2none */
6892 }
6893 break;
6894
6895
6896 default:
6897 break;
6898 }
6899 }
6900}
6901
6902
6903/*
6904 OptExpSeen - returns TRUE if we can see an optional expression in the factor.
6905 This is not the same as epsilon. Example { '+' } matches epsilon as
6906 well as { '+' | '-' } but OptExpSeen returns TRUE in the second case
6907 and FALSE in the first.
6908*/
6909
6910static unsigned int OptExpSeen (pge_FactorDesc f)
6911{
6912 if (f == NULL)
6913 {
6914 return FALSE;
6915 }
6916 else
6917 {
6918 switch (f->type)
6919 {
6920 case pge_id:
6921 case pge_lit:
6922 return FALSE;
6923 break;
6924
6925 case pge_sub:
6926 return FALSE; /* is this correct? */
6927 break;
6928
6929 case pge_opt:
6930 case pge_mult:
6931 return ((f->expr != NULL) && (f->expr->term != NULL)) && (f->expr->term->next != NULL); /* is this correct? */
6932 break;
6933
6934 case pge_m2:
6935 return TRUE;
6936 break;
6937
6938
6939 default:
6940 break;
6941 }
6942 }
6943 PushBackInput_WarnError ((const char *) "all cases were not handled", 26);
6944 WasNoError = FALSE;
6945 ReturnException ("m2/gm2-auto/pge.mod", 1, 7);
6946 __builtin_unreachable ();
6947}
6948
6949
6950/*
6951 RecoverTerm -
6952*/
6953
6954static void RecoverTerm (pge_TermDesc t, pge_m2condition new_, pge_m2condition old)
6955{
6956 unsigned int LastWasM2Only;
6957 unsigned int alternative;
6958 pge_SetDesc to;
6959
6960 LastWasM2Only = (t->factor->type == pge_m2) && (t->factor->next == NULL); /* does the factor only contain inline code? */
6961 to = NULL;
6962 CalcFirstTerm (t, NULL, &to);
6963 alternative = FALSE;
6964 if (t->next != NULL)
6965 {
6966 new_ = pge_m2if;
6967 }
6968 while (t != NULL)
6969 {
6970 EmitFileLineTag (t->line);
6971 LastWasM2Only = (t->factor->type == pge_m2) && (t->factor->next == NULL);
6972 if ((t->factor->type == pge_m2) && (new_ == pge_m2elsif))
6973 {
6974 new_ = pge_m2if;
6975 IndentString ((const char *) "ELSE", 4);
6976 Output_WriteLn ();
6977 Indent += 3;
6978 RecoverFactor (t->factor, pge_m2none, NULL);
6979 alternative = FALSE;
6980 }
6981 else
6982 {
6983 RecoverFactor (t->factor, new_, NULL);
6984 }
6985 if (t->next != NULL)
6986 {
6987 new_ = pge_m2elsif;
6988 alternative = TRUE;
6989 }
6990 t = t->next;
6991 }
6992 if ((new_ == pge_m2if) || (new_ == pge_m2elsif))
6993 {
6994 if (alternative && (old != pge_m2while))
6995 {
6996 IndentString ((const char *) "ELSE", 4);
6997 Output_WriteLn ();
6998 Indent += 3;
6999 IndentString ((const char *) "", 0);
7000 Output_WriteKey (ErrorProcArray);
7001 Output_WriteString ((const char *) "('expecting one of: ", 20);
7002 EmitSetName (to, static_cast<unsigned int> (0), static_cast<unsigned int> (0));
7003 Output_WriteString ((const char *) "')", 2);
7004 Output_WriteLn ();
7005 Indent -= 3;
7006 }
7007 else if (LastWasM2Only)
7008 {
7009 /* avoid dangling else. */
7010 Indent -= 3;
7011 }
7012 IndentString ((const char *) "END ;", 5);
7013 Output_WriteLn ();
7014 }
7015 else if (new_ == pge_m2while)
7016 {
7017 /* avoid dangling else. */
7018 IndentString ((const char *) "END (* while *) ;", 17);
7019 Output_WriteLn ();
7020 }
7021 else if (LastWasM2Only)
7022 {
7023 /* avoid dangling else. */
7024 Indent -= 3;
7025 }
7026}
7027
7028
7029/*
7030 RecoverExpression -
7031*/
7032
7033static void RecoverExpression (pge_ExpressionDesc e, pge_m2condition new_, pge_m2condition old)
7034{
7035 if (e != NULL)
7036 {
7037 EmitFileLineTag (e->line);
7038 RecoverTerm (e->term, new_, old);
7039 }
7040}
7041
7042
7043/*
7044 RecoverStatement -
7045*/
7046
7047static void RecoverStatement (pge_StatementDesc s, pge_m2condition m)
7048{
7049 if (s != NULL)
7050 {
7051 EmitFileLineTag (s->line);
7052 RecoverExpression (s->expr, m, pge_m2none);
7053 }
7054}
7055
7056
7057/*
7058 EmitFirstFactor - generate a list of all first tokens between the range: low..high.
7059*/
7060
7061static void EmitFirstFactor (pge_FactorDesc f, unsigned int low, unsigned int high)
7062{
7063}
7064
7065
7066/*
7067 EmitUsed -
7068*/
7069
7070static void EmitUsed (unsigned int wordno)
7071{
7072 if (! ((((1 << (wordno)) & (ParametersUsed)) != 0)))
7073 {
7074 Output_WriteString ((const char *) " (* <* unused *> *) ", 20);
7075 }
7076}
7077
7078
7079/*
7080 EmitStopParameters - generate the stop set.
7081*/
7082
7083static void EmitStopParameters (unsigned int FormalParameters)
7084{
7085 unsigned int i;
7086
7087 if (LargestValue <= MaxElementsInSet)
7088 {
7089 Output_WriteString ((const char *) "stopset", 7);
7090 if (FormalParameters)
7091 {
7092 Output_WriteString ((const char *) ": SetOfStop", 11);
7093 EmitUsed (0);
7094 }
7095 else
7096 {
7097 ParametersUsed |= (1 << (0 ));
7098 }
7099 }
7100 else
7101 {
7102 i = 0;
7103 do {
7104 Output_WriteString ((const char *) "stopset", 7);
7105 Output_WriteCard (i, 0);
7106 if (FormalParameters)
7107 {
7108 Output_WriteString ((const char *) ": SetOfStop", 11);
7109 Output_WriteCard (i, 0);
7110 EmitUsed (i);
7111 }
7112 else
7113 {
7114 ParametersUsed |= (1 << (i ));
7115 }
7116 i += 1;
7117 if ((i*MaxElementsInSet) < LargestValue)
7118 {
7119 /* avoid gcc warning by using compound statement even if not strictly necessary. */
7120 if (FormalParameters)
7121 {
7122 Output_WriteString ((const char *) "; ", 2);
7123 }
7124 else
7125 {
7126 Output_WriteString ((const char *) ", ", 2);
7127 }
7128 }
7129 } while (! ((i*MaxElementsInSet) >= LargestValue));
7130 }
7131}
7132
7133
7134/*
7135 IsBetween - returns TRUE if the value of the token, string, is
7136 in the range: low..high
7137*/
7138
7139static unsigned int IsBetween (NameKey_Name string, unsigned int low, unsigned int high)
7140{
7141 return ((SymbolKey_GetSymKey (Values, string)) >= low) && ((SymbolKey_GetSymKey (Values, string)) <= high);
7142 /* static analysis guarentees a RETURN statement will be used before here. */
7143 __builtin_unreachable ();
7144}
7145
7146
7147/*
7148 IsEmptySet - returns TRUE if no elements exist in set, to, with values, low..high.
7149*/
7150
7151static unsigned int IsEmptySet (pge_SetDesc to, unsigned int low, unsigned int high)
7152{
7153 while (to != NULL)
7154 {
7155 switch (to->type)
7156 {
7157 case pge_tokel:
7158 if (IsBetween (to->string, low, high))
7159 {
7160 return FALSE;
7161 }
7162 break;
7163
7164 case pge_litel:
7165 if (IsBetween (SymbolKey_GetSymKey (Aliases, to->string), low, high))
7166 {
7167 return FALSE;
7168 }
7169 break;
7170
7171 case pge_idel:
7172 PushBackInput_WarnError ((const char *) "not expecting ident in first symbol list", 40);
7173 WasNoError = FALSE;
7174 break;
7175
7176
7177 default:
7178 PushBackInput_WarnError ((const char *) "unknown enuneration element", 27);
7179 WasNoError = FALSE;
7180 break;
7181 }
7182 to = to->next;
7183 }
7184 return TRUE;
7185 /* static analysis guarentees a RETURN statement will be used before here. */
7186 __builtin_unreachable ();
7187}
7188
7189
7190/*
7191 EmitSet - emits the tokens in the set, to, which have values low..high
7192*/
7193
7194static void EmitSet (pge_SetDesc to, unsigned int low, unsigned int high)
7195{
7196 unsigned int first;
7197
7198 first = TRUE;
7199 while (to != NULL)
7200 {
7201 switch (to->type)
7202 {
7203 case pge_tokel:
7204 if ((high == 0) || (IsBetween (to->string, low, high)))
7205 {
7206 if (! first)
7207 {
7208 Output_WriteString ((const char *) ", ", 2);
7209 }
7210 Output_WriteKey (to->string);
7211 first = FALSE;
7212 }
7213 break;
7214
7215 case pge_litel:
7216 if ((high == 0) || (IsBetween (SymbolKey_GetSymKey (Aliases, to->string), low, high)))
7217 {
7218 if (! first)
7219 {
7220 Output_WriteString ((const char *) ", ", 2);
7221 }
7222 Output_WriteKey (SymbolKey_GetSymKey (Aliases, to->string));
7223 first = FALSE;
7224 }
7225 break;
7226
7227 case pge_idel:
7228 PushBackInput_WarnError ((const char *) "not expecting ident in first symbol list", 40);
7229 WasNoError = FALSE;
7230 break;
7231
7232
7233 default:
7234 PushBackInput_WarnError ((const char *) "unknown enuneration element", 27);
7235 WasNoError = FALSE;
7236 break;
7237 }
7238 to = to->next;
7239 }
7240}
7241
7242
7243/*
7244 EmitSetName - emits the tokens in the set, to, which have values low..high, using
7245 their names.
7246*/
7247
7248static void EmitSetName (pge_SetDesc to, unsigned int low, unsigned int high)
7249{
7250 while (to != NULL)
7251 {
7252 switch (to->type)
7253 {
7254 case pge_tokel:
7255 if ((high == 0) || (IsBetween (to->string, low, high)))
7256 {
7257 /* avoid gcc warning by using compound statement even if not strictly necessary. */
7258 if ((NameKey_MakeKey ((const char *) "'", 1)) == (SymbolKey_GetSymKey (ReverseAliases, to->string)))
7259 {
7260 Output_WriteString ((const char *) "single quote", 12);
7261 }
7262 else
7263 {
7264 KeyWord (SymbolKey_GetSymKey (ReverseAliases, to->string));
7265 }
7266 }
7267 break;
7268
7269 case pge_litel:
7270 if ((high == 0) || (IsBetween (SymbolKey_GetSymKey (Aliases, to->string), low, high)))
7271 {
7272 Output_WriteKey (to->string);
7273 }
7274 break;
7275
7276 case pge_idel:
7277 PushBackInput_WarnError ((const char *) "not expecting ident in first symbol list", 40);
7278 WasNoError = FALSE;
7279 break;
7280
7281
7282 default:
7283 PushBackInput_WarnError ((const char *) "unknown enuneration element", 27);
7284 WasNoError = FALSE;
7285 break;
7286 }
7287 to = to->next;
7288 if (to != NULL)
7289 {
7290 Output_Write (' ');
7291 }
7292 }
7293}
7294
7295
7296/*
7297 EmitStopParametersAndSet - generates the stop parameters together with a set
7298 inclusion of all the symbols in set, to.
7299*/
7300
7301static void EmitStopParametersAndSet (pge_SetDesc to)
7302{
7303 unsigned int i;
7304
7305 if (LargestValue <= MaxElementsInSet)
7306 {
7307 /* avoid dangling else. */
7308 Output_WriteString ((const char *) "stopset", 7);
7309 ParametersUsed |= (1 << (0 ));
7310 if ((to != NULL) && ((NumberOfElements (to, static_cast<unsigned int> (0), static_cast<unsigned int> (MaxElementsInSet-1))) > 0))
7311 {
7312 Output_WriteString ((const char *) " + SetOfStop", 12);
7313 Output_Write ('{');
7314 EmitSet (to, static_cast<unsigned int> (0), static_cast<unsigned int> (MaxElementsInSet-1));
7315 Output_Write ('}');
7316 }
7317 }
7318 else
7319 {
7320 i = 0;
7321 do {
7322 Output_WriteString ((const char *) "stopset", 7);
7323 Output_WriteCard (i, 0);
7324 ParametersUsed |= (1 << (i ));
7325 if ((to != NULL) && ((NumberOfElements (to, i*MaxElementsInSet, ((i+1)*MaxElementsInSet)-1)) > 0))
7326 {
7327 Output_WriteString ((const char *) " + SetOfStop", 12);
7328 Output_WriteCard (i, 0);
7329 Output_Write ('{');
7330 EmitSet (to, i*MaxElementsInSet, ((i+1)*MaxElementsInSet)-1);
7331 Output_Write ('}');
7332 }
7333 i += 1;
7334 if ((i*MaxElementsInSet) < LargestValue)
7335 {
7336 Output_WriteString ((const char *) ", ", 2);
7337 }
7338 } while (! ((i*MaxElementsInSet) >= LargestValue));
7339 }
7340}
7341
7342
7343/*
7344 EmitSetAsParameters - generates the first symbols as parameters to a set function.
7345*/
7346
7347static void EmitSetAsParameters (pge_SetDesc to)
7348{
7349 unsigned int i;
7350
7351 if (LargestValue <= MaxElementsInSet)
7352 {
7353 Output_Write ('{');
7354 EmitSet (to, static_cast<unsigned int> (0), static_cast<unsigned int> (MaxElementsInSet-1));
7355 }
7356 else
7357 {
7358 i = 0;
7359 do {
7360 Output_Write ('{');
7361 EmitSet (to, i*MaxElementsInSet, ((i+1)*MaxElementsInSet)-1);
7362 i += 1;
7363 if (((i+1)*MaxElementsInSet) > LargestValue)
7364 {
7365 Output_WriteString ((const char *) "}, ", 3);
7366 }
7367 } while (! (((i+1)*MaxElementsInSet) >= LargestValue));
7368 }
7369 Output_Write ('}');
7370}
7371
7372
7373/*
7374 EmitStopParametersAndFollow - generates the stop parameters together with a set
7375 inclusion of all the follow symbols for subsequent
7376 sentances.
7377*/
7378
7379static void EmitStopParametersAndFollow (pge_FactorDesc f, pge_m2condition m)
7380{
7381 pge_SetDesc to;
7382
7383 to = NULL;
7384 /*
7385 IF m=m2while
7386 THEN
7387 CalcFirstFactor(f, NIL, to)
7388 END ;
7389 */
7390 CollectFollow (&to, f->followinfo);
7391 EmitStopParametersAndSet (to);
7392 if (Debugging)
7393 {
7394 Output_WriteLn ();
7395 Output_WriteString ((const char *) "factor is: ", 11);
7396 PrettyCommentFactor (f, StrLib_StrLen ((const char *) "factor is: ", 11));
7397 Output_WriteLn ();
7398 Output_WriteString ((const char *) "follow set:", 11);
7399 EmitSet (to, static_cast<unsigned int> (0), static_cast<unsigned int> (0));
7400 Output_WriteLn ();
7401 }
7402}
7403
7404
7405/*
7406 EmitFirstAsParameters -
7407*/
7408
7409static void EmitFirstAsParameters (pge_FactorDesc f)
7410{
7411 pge_SetDesc to;
7412
7413 to = NULL;
7414 CalcFirstFactor (f, NULL, &to);
7415 EmitSetAsParameters (to);
7416}
7417
7418
7419/*
7420 RecoverProduction - only encode grammer rules which are not special.
7421 Generate error recovery code.
7422*/
7423
7424static void RecoverProduction (pge_ProductionDesc p)
7425{
7426 DynamicStrings_String s;
7427
7428 if ((p != NULL) && (! p->firstsolved || ((p->statement != NULL) && (p->statement->expr != NULL))))
7429 {
7430 BeginningOfLine = TRUE;
7431 Indent = 0;
7432 Output_WriteLn ();
7433 OnLineStart = FALSE;
7434 EmitFileLineTag (p->line);
7435 IndentString ((const char *) "PROCEDURE ", 10);
7436 Output_WriteKey (GetDefinitionName (p));
7437 Output_WriteString ((const char *) " (", 2);
7438 ParametersUsed = (unsigned int) 0;
7439 Output_StartBuffer ();
7440 Output_WriteString ((const char *) ") ;", 3);
7441 VarProduction (p);
7442 Output_WriteLn ();
7443 OnLineStart = FALSE;
7444 EmitFileLineTag (p->line);
7445 Indent = 0;
7446 IndentString ((const char *) "BEGIN", 5);
7447 Output_WriteLn ();
7448 OnLineStart = FALSE;
7449 EmitFileLineTag (p->line);
7450 Indent = 3;
7451 RecoverStatement (p->statement, pge_m2none);
7452 Indent = 0;
7453 IndentString ((const char *) "END ", 4);
7454 Output_WriteKey (GetDefinitionName (p));
7455 Output_WriteString ((const char *) " ;", 2);
7456 Output_WriteLn ();
7457 Output_WriteLn ();
7458 Output_WriteLn ();
7459 s = Output_EndBuffer ();
7460 EmitStopParameters (TRUE);
7461 Output_KillWriteS (s);
7462 }
7463}
7464
7465
7466/*
7467 IsWhite - returns TRUE if, ch, is a space or a tab.
7468*/
7469
7470static unsigned int IsWhite (char ch)
7471{
7472 return ((ch == ' ') || (ch == ASCII_tab)) || (ch == ASCII_lf);
7473 /* static analysis guarentees a RETURN statement will be used before here. */
7474 __builtin_unreachable ();
7475}
7476
7477
7478/*
7479 FindStr - returns TRUE if, str, was seen inside the code hunk
7480*/
7481
7482static unsigned int FindStr (pge_CodeHunk *code, unsigned int *i, const char *str_, unsigned int _str_high)
7483{
7484 unsigned int j;
7485 unsigned int k;
7486 pge_CodeHunk t;
7487 char str[_str_high+1];
7488
7489 /* make a local copy of each unbounded array. */
7490 memcpy (str, str_, _str_high+1);
7491
7492 t = (*code);
7493 k = (StrLib_StrLen ((const char *) &(*code)->codetext.array[0], MaxCodeHunkLength))+1;
7494 while (t != NULL)
7495 {
7496 do {
7497 while ((k > 0) && (IsWhite (t->codetext.array[k-1])))
7498 {
7499 k -= 1;
7500 }
7501 if (k == 0)
7502 {
7503 t = t->next;
7504 k = MaxCodeHunkLength+1;
7505 }
7506 } while (! ((t == NULL) || (! (IsWhite (t->codetext.array[k-1])))));
7507 /* found another word check it */
7508 if (t != NULL)
7509 {
7510 j = StrLib_StrLen ((const char *) str, _str_high);
7511 (*i) = k;
7512 while (((t != NULL) && (j > 0)) && ((str[j-1] == t->codetext.array[k-1]) || ((IsWhite (str[j-1])) && (IsWhite (t->codetext.array[k-1])))))
7513 {
7514 j -= 1;
7515 k -= 1;
7516 if (j == 0)
7517 {
7518 /* found word remember position */
7519 (*code) = t;
7520 }
7521 if (k == 0)
7522 {
7523 t = t->next;
7524 k = MaxCodeHunkLength+1;
7525 }
7526 }
7527 if (k > 0)
7528 {
7529 k -= 1;
7530 }
7531 else
7532 {
7533 t = t->next;
7534 }
7535 }
7536 }
7537 return (t == NULL) && (j == 0);
7538 /* static analysis guarentees a RETURN statement will be used before here. */
7539 __builtin_unreachable ();
7540}
7541
7542
7543/*
7544 WriteUpto -
7545*/
7546
7547static void WriteUpto (pge_CodeHunk code, pge_CodeHunk upto, unsigned int limit)
7548{
7549 if (code != upto)
7550 {
7551 WriteUpto (code->next, upto, limit);
7552 Output_WriteString ((const char *) &code->codetext.array[0], MaxCodeHunkLength);
7553 }
7554 else
7555 {
7556 while ((limit <= MaxCodeHunkLength) && (code->codetext.array[limit] != ASCII_nul))
7557 {
7558 Output_Write (code->codetext.array[limit]);
7559 limit += 1;
7560 }
7561 }
7562}
7563
7564
7565/*
7566 CheckForVar - checks for any local variables which need to be emitted during
7567 this production.
7568*/
7569
7570static void CheckForVar (pge_CodeHunk code)
7571{
7572 unsigned int i;
7573 pge_CodeHunk t;
7574
7575 t = code;
7576 if ((FindStr (&t, &i, (const char *) "VAR", 3)) && EmitCode)
7577 {
7578 if (! EmittedVar)
7579 {
7580 Output_WriteLn ();
7581 Indent = 0;
7582 IndentString ((const char *) "VAR", 3);
7583 Indent += 3;
7584 Output_WriteLn ();
7585 EmittedVar = TRUE;
7586 }
7587 WriteUpto (code, t, i);
7588 }
7589}
7590
7591
7592/*
7593 VarFactor -
7594*/
7595
7596static void VarFactor (pge_FactorDesc f)
7597{
7598 while (f != NULL)
7599 {
7600 switch (f->type)
7601 {
7602 case pge_id:
7603 break;
7604
7605 case pge_lit:
7606 break;
7607
7608 case pge_sub:
7609 case pge_opt:
7610 case pge_mult:
7611 VarExpression (f->expr);
7612 break;
7613
7614 case pge_m2:
7615 CheckForVar (f->code->code);
7616 break;
7617
7618
7619 default:
7620 break;
7621 }
7622 f = f->next;
7623 }
7624}
7625
7626
7627/*
7628 VarTerm -
7629*/
7630
7631static void VarTerm (pge_TermDesc t)
7632{
7633 while (t != NULL)
7634 {
7635 VarFactor (t->factor);
7636 t = t->next;
7637 }
7638}
7639
7640
7641/*
7642 VarExpression -
7643*/
7644
7645static void VarExpression (pge_ExpressionDesc e)
7646{
7647 if (e != NULL)
7648 {
7649 VarTerm (e->term);
7650 }
7651}
7652
7653
7654/*
7655 VarStatement -
7656*/
7657
7658static void VarStatement (pge_StatementDesc s)
7659{
7660 if (s != NULL)
7661 {
7662 VarExpression (s->expr);
7663 }
7664}
7665
7666
7667/*
7668 VarProduction - writes out all variable declarations.
7669*/
7670
7671static void VarProduction (pge_ProductionDesc p)
7672{
7673 EmittedVar = FALSE;
7674 if (p != NULL)
7675 {
7676 VarStatement (p->statement);
7677 }
7678}
7679
7680
7681/*
7682 In - returns TRUE if token, s, is already in the set, to.
7683*/
7684
7685static unsigned int In (pge_SetDesc to, NameKey_Name s)
7686{
7687 while (to != NULL)
7688 {
7689 switch (to->type)
7690 {
7691 case pge_idel:
7692 if (s == to->ident->name)
7693 {
7694 return TRUE;
7695 }
7696 break;
7697
7698 case pge_tokel:
7699 case pge_litel:
7700 if (s == to->string)
7701 {
7702 return TRUE;
7703 }
7704 break;
7705
7706
7707 default:
7708 PushBackInput_WarnError ((const char *) "internal error CASE type not known", 34);
7709 WasNoError = FALSE;
7710 break;
7711 }
7712 to = to->next;
7713 }
7714 return FALSE;
7715 /* static analysis guarentees a RETURN statement will be used before here. */
7716 __builtin_unreachable ();
7717}
7718
7719
7720/*
7721 IntersectionIsNil - given two set lists, s1, s2, return TRUE if the
7722 s1 * s2 = {}
7723*/
7724
7725static unsigned int IntersectionIsNil (pge_SetDesc s1, pge_SetDesc s2)
7726{
7727 while (s1 != NULL)
7728 {
7729 switch (s1->type)
7730 {
7731 case pge_idel:
7732 if (In (s2, s1->ident->name))
7733 {
7734 return FALSE;
7735 }
7736 break;
7737
7738 case pge_tokel:
7739 case pge_litel:
7740 if (In (s2, s1->string))
7741 {
7742 return FALSE;
7743 }
7744 break;
7745
7746
7747 default:
7748 PushBackInput_WarnError ((const char *) "internal error CASE type not known", 34);
7749 WasNoError = FALSE;
7750 break;
7751 }
7752 s1 = s1->next;
7753 }
7754 return TRUE;
7755 /* static analysis guarentees a RETURN statement will be used before here. */
7756 __builtin_unreachable ();
7757}
7758
7759
7760/*
7761 AddSet - adds a first symbol to a production.
7762*/
7763
7764static void AddSet (pge_SetDesc *to, NameKey_Name s)
7765{
7766 pge_SetDesc d;
7767
7768 if (! (In ((*to), s)))
7769 {
7770 d = NewSetDesc ();
7771 d->type = pge_tokel;
7772 d->string = s;
7773 d->next = (*to);
7774 (*to) = d;
7775 Finished = FALSE;
7776 }
7777}
7778
7779
7780/*
7781 OrSet -
7782*/
7783
7784static void OrSet (pge_SetDesc *to, pge_SetDesc from)
7785{
7786 while (from != NULL)
7787 {
7788 switch (from->type)
7789 {
7790 case pge_tokel:
7791 AddSet (to, from->string);
7792 break;
7793
7794 case pge_litel:
7795 AddSet (to, SymbolKey_GetSymKey (Aliases, from->string));
7796 break;
7797
7798 case pge_idel:
7799 PushBackInput_WarnError ((const char *) "not expecting ident in first symbol list", 40);
7800 WasNoError = FALSE;
7801 break;
7802
7803
7804 default:
7805 Debug_Halt ((const char *) "unknown element in enumeration type", 35, 4122, (const char *) "m2/gm2-auto/pge.mod", 19);
7806 break;
7807 }
7808 from = from->next;
7809 }
7810}
7811
7812
7813/*
7814 CalcFirstFactor -
7815*/
7816
7817static void CalcFirstFactor (pge_FactorDesc f, pge_ProductionDesc from, pge_SetDesc *to)
7818{
7819 while (f != NULL)
7820 {
7821 switch (f->type)
7822 {
7823 case pge_id:
7824 if (f->ident->definition == NULL)
7825 {
7826 WarnError1 ((const char *) "no rule found for an 'ident' called '%s'", 40, f->ident->name);
7827 M2RTS_HALT (-1);
7828 __builtin_unreachable ();
7829 }
7830 OrSet (to, f->ident->definition->first);
7831 if ((GetReachEnd (f->ident->definition->followinfo)) == pge_false)
7832 {
7833 return ;
7834 }
7835 break;
7836
7837 case pge_lit:
7838 if ((SymbolKey_GetSymKey (Aliases, f->string)) == SymbolKey_NulKey)
7839 {
7840 WarnError1 ((const char *) "unknown token for '%s'", 22, f->string);
7841 WasNoError = FALSE;
7842 }
7843 else
7844 {
7845 AddSet (to, SymbolKey_GetSymKey (Aliases, f->string));
7846 }
7847 return ;
7848 break;
7849
7850 case pge_sub:
7851 case pge_opt:
7852 case pge_mult:
7853 CalcFirstExpression (f->expr, from, to);
7854 break;
7855
7856 case pge_m2:
7857 break;
7858
7859
7860 default:
7861 break;
7862 }
7863 f = f->next;
7864 }
7865}
7866
7867
7868/*
7869 CalcFirstTerm -
7870*/
7871
7872static void CalcFirstTerm (pge_TermDesc t, pge_ProductionDesc from, pge_SetDesc *to)
7873{
7874 while (t != NULL)
7875 {
7876 CalcFirstFactor (t->factor, from, to);
7877 t = t->next;
7878 }
7879}
7880
7881
7882/*
7883 CalcFirstExpression -
7884*/
7885
7886static void CalcFirstExpression (pge_ExpressionDesc e, pge_ProductionDesc from, pge_SetDesc *to)
7887{
7888 if (e != NULL)
7889 {
7890 CalcFirstTerm (e->term, from, to);
7891 }
7892}
7893
7894
7895/*
7896 CalcFirstStatement -
7897*/
7898
7899static void CalcFirstStatement (pge_StatementDesc s, pge_ProductionDesc from, pge_SetDesc *to)
7900{
7901 if (s != NULL)
7902 {
7903 CalcFirstExpression (s->expr, from, to);
7904 }
7905}
7906
7907
7908/*
7909 CalcFirstProduction - calculates all of the first symbols for the grammer
7910*/
7911
7912static void CalcFirstProduction (pge_ProductionDesc p, pge_ProductionDesc from, pge_SetDesc *to)
7913{
7914 pge_SetDesc s;
7915
7916 if (p != NULL)
7917 {
7918 /* avoid gcc warning by using compound statement even if not strictly necessary. */
7919 if (p->firstsolved)
7920 {
7921 s = p->first;
7922 while (s != NULL)
7923 {
7924 switch (s->type)
7925 {
7926 case pge_idel:
7927 CalcFirstProduction (s->ident->definition, from, to);
7928 break;
7929
7930 case pge_tokel:
7931 case pge_litel:
7932 AddSet (to, s->string);
7933 break;
7934
7935
7936 default:
7937 break;
7938 }
7939 s = s->next;
7940 }
7941 }
7942 else
7943 {
7944 CalcFirstStatement (p->statement, from, to);
7945 }
7946 }
7947}
7948
7949static void WorkOutFollowFactor (pge_FactorDesc f, pge_SetDesc *followset, pge_SetDesc after)
7950{
7951 pge_TraverseResult foundepsilon;
7952 pge_TraverseResult canreachend;
7953
7954 /*
7955 WorkOutFollow -
7956 */
7957 foundepsilon = pge_true;
7958 canreachend = pge_true;
7959 while ((f != NULL) && (foundepsilon == pge_true))
7960 {
7961 switch (f->type)
7962 {
7963 case pge_id:
7964 if (f->ident->definition == NULL)
7965 {
7966 WarnError1 ((const char *) "no rule found for an 'ident' called '%s'", 40, f->ident->name);
7967 M2RTS_HALT (-1);
7968 __builtin_unreachable ();
7969 }
7970 OrSet (followset, f->ident->definition->first);
7971 break;
7972
7973 case pge_lit:
7974 AddSet (followset, SymbolKey_GetSymKey (Aliases, f->string));
7975 break;
7976
7977 case pge_sub:
7978 WorkOutFollowExpression (f->expr, followset, NULL);
7979 break;
7980
7981 case pge_opt:
7982 WorkOutFollowExpression (f->expr, followset, NULL);
7983 break;
7984
7985 case pge_mult:
7986 WorkOutFollowExpression (f->expr, followset, NULL);
7987 break;
7988
7989 case pge_m2:
7990 break;
7991
7992
7993 default:
7994 break;
7995 }
7996 if ((GetEpsilon (f->followinfo)) == pge_unknown)
7997 {
7998 PushBackInput_WarnError ((const char *) "internal error: epsilon unknown", 31);
7999 PrettyCommentFactor (f, 3);
8000 WasNoError = FALSE;
8001 }
8002 foundepsilon = GetEpsilon (f->followinfo);
8003 canreachend = GetReachEnd (f->followinfo); /* only goes from FALSE -> TRUE */
8004 f = f->next; /* only goes from FALSE -> TRUE */
8005 }
8006 if (canreachend == pge_true)
8007 {
8008 OrSet (followset, after);
8009 }
8010}
8011
8012
8013/*
8014 WorkOutFollowTerm -
8015*/
8016
8017static void WorkOutFollowTerm (pge_TermDesc t, pge_SetDesc *followset, pge_SetDesc after)
8018{
8019 if (t != NULL)
8020 {
8021 while (t != NULL)
8022 {
8023 WorkOutFollowFactor (t->factor, followset, after); /* { '|' Term } */
8024 t = t->next; /* { '|' Term } */
8025 }
8026 }
8027}
8028
8029
8030/*
8031 WorkOutFollowExpression -
8032*/
8033
8034static void WorkOutFollowExpression (pge_ExpressionDesc e, pge_SetDesc *followset, pge_SetDesc after)
8035{
8036 if (e != NULL)
8037 {
8038 WorkOutFollowTerm (e->term, followset, after);
8039 }
8040}
8041
8042
8043/*
8044 CollectFollow - collects the follow set from, f, into, to.
8045*/
8046
8047static void CollectFollow (pge_SetDesc *to, pge_FollowDesc f)
8048{
8049 OrSet (to, f->follow);
8050}
8051
8052
8053/*
8054 CalcFollowFactor -
8055*/
8056
8057static void CalcFollowFactor (pge_FactorDesc f, pge_SetDesc after)
8058{
8059 while (f != NULL)
8060 {
8061 switch (f->type)
8062 {
8063 case pge_id:
8064 WorkOutFollowFactor (f->next, &f->followinfo->follow, after);
8065 break;
8066
8067 case pge_lit:
8068 WorkOutFollowFactor (f->next, &f->followinfo->follow, after);
8069 break;
8070
8071 case pge_opt:
8072 case pge_sub:
8073 CalcFirstFactor (f->next, NULL, &f->followinfo->follow);
8074 if ((f->next == NULL) || ((GetReachEnd (f->next->followinfo)) == pge_true))
8075 {
8076 OrSet (&f->followinfo->follow, after);
8077 CalcFollowExpression (f->expr, f->followinfo->follow);
8078 }
8079 else
8080 {
8081 CalcFollowExpression (f->expr, f->followinfo->follow);
8082 }
8083 break;
8084
8085 case pge_mult:
8086 CalcFirstFactor (f, NULL, &f->followinfo->follow);
8087 /* include first as we may repeat this sentance */
8088 if (Debugging)
8089 {
8090 StrIO_WriteLn ();
8091 StrIO_WriteString ((const char *) "found mult: and first is: ", 26);
8092 EmitSet (f->followinfo->follow, static_cast<unsigned int> (0), static_cast<unsigned int> (0));
8093 StrIO_WriteLn ();
8094 }
8095 if ((f->next == NULL) || ((GetReachEnd (f->next->followinfo)) == pge_true))
8096 {
8097 OrSet (&f->followinfo->follow, after);
8098 CalcFollowExpression (f->expr, f->followinfo->follow);
8099 }
8100 else
8101 {
8102 CalcFollowExpression (f->expr, f->followinfo->follow);
8103 }
8104 break;
8105
8106
8107 default:
8108 break;
8109 }
8110 f = f->next;
8111 }
8112}
8113
8114
8115/*
8116 CalcFollowTerm -
8117*/
8118
8119static void CalcFollowTerm (pge_TermDesc t, pge_SetDesc after)
8120{
8121 if (t != NULL)
8122 {
8123 while (t != NULL)
8124 {
8125 CalcFollowFactor (t->factor, after); /* { '|' Term } */
8126 t = t->next; /* { '|' Term } */
8127 }
8128 }
8129}
8130
8131
8132/*
8133 CalcFollowExpression -
8134*/
8135
8136static void CalcFollowExpression (pge_ExpressionDesc e, pge_SetDesc after)
8137{
8138 if (e != NULL)
8139 {
8140 CalcFollowTerm (e->term, after);
8141 }
8142}
8143
8144
8145/*
8146 CalcFollowStatement - given a bnf statement generate the follow set.
8147*/
8148
8149static void CalcFollowStatement (pge_StatementDesc s)
8150{
8151 if (s != NULL)
8152 {
8153 CalcFollowExpression (s->expr, NULL);
8154 }
8155}
8156
8157
8158/*
8159 CalcFollowProduction -
8160*/
8161
8162static void CalcFollowProduction (pge_ProductionDesc p)
8163{
8164 if (p != NULL)
8165 {
8166 CalcFollowStatement (p->statement);
8167 }
8168}
8169
8170
8171/*
8172 CalcEpsilonFactor -
8173*/
8174
8175static void CalcEpsilonFactor (pge_FactorDesc f)
8176{
8177 while (f != NULL)
8178 {
8179 switch (f->type)
8180 {
8181 case pge_id:
8182 AssignEpsilon ((GetEpsilon (f->ident->definition->followinfo)) != pge_unknown, f->followinfo, GetEpsilon (f->ident->definition->followinfo));
8183 break;
8184
8185 case pge_lit:
8186 AssignEpsilon (TRUE, f->followinfo, pge_false);
8187 break;
8188
8189 case pge_sub:
8190 CalcEpsilonExpression (f->expr);
8191 AssignEpsilon ((GetEpsilon (f->expr->followinfo)) != pge_unknown, f->followinfo, GetEpsilon (f->expr->followinfo));
8192 break;
8193
8194 case pge_m2:
8195 AssignEpsilon (TRUE, f->followinfo, pge_true);
8196 break;
8197
8198 case pge_opt:
8199 case pge_mult:
8200 CalcEpsilonExpression (f->expr);
8201 AssignEpsilon (TRUE, f->followinfo, pge_true);
8202 break;
8203
8204
8205 default:
8206 break;
8207 }
8208 f = f->next;
8209 }
8210}
8211
8212
8213/*
8214 CalcEpsilonTerm -
8215*/
8216
8217static void CalcEpsilonTerm (pge_TermDesc t)
8218{
8219 if (t != NULL)
8220 {
8221 while (t != NULL)
8222 {
8223 if (t->factor != NULL)
8224 {
8225 switch (GetReachEnd (t->factor->followinfo))
8226 {
8227 case pge_true:
8228 AssignEpsilon (TRUE, t->followinfo, pge_true);
8229 break;
8230
8231 case pge_false:
8232 AssignEpsilon (TRUE, t->followinfo, pge_false);
8233 break;
8234
8235 case pge_unknown:
8236 break;
8237
8238
8239 default:
8240 break;
8241 }
8242 }
8243 CalcEpsilonFactor (t->factor); /* { '|' Term } */
8244 t = t->next;
8245 }
8246 }
8247}
8248
8249
8250/*
8251 CalcEpsilonExpression -
8252*/
8253
8254static void CalcEpsilonExpression (pge_ExpressionDesc e)
8255{
8256 pge_TermDesc t;
8257 pge_TraverseResult result;
8258
8259 if (e != NULL)
8260 {
8261 CalcEpsilonTerm (e->term);
8262 if ((GetEpsilon (e->followinfo)) == pge_unknown)
8263 {
8264 result = pge_unknown;
8265 t = e->term;
8266 while (t != NULL)
8267 {
8268 if ((GetEpsilon (t->followinfo)) != pge_unknown)
8269 {
8270 stop ();
8271 }
8272 switch (GetEpsilon (t->followinfo))
8273 {
8274 case pge_unknown:
8275 break;
8276
8277 case pge_true:
8278 result = pge_true;
8279 break;
8280
8281 case pge_false:
8282 if (result != pge_true)
8283 {
8284 result = pge_false;
8285 }
8286 break;
8287
8288
8289 default:
8290 break;
8291 }
8292 t = t->next;
8293 }
8294 AssignEpsilon (result != pge_unknown, e->followinfo, result);
8295 }
8296 }
8297}
8298
8299
8300/*
8301 CalcEpsilonStatement - given a bnf statement generate the follow set.
8302*/
8303
8304static void CalcEpsilonStatement (pge_StatementDesc s)
8305{
8306 if (s != NULL)
8307 {
8308 if (s->expr != NULL)
8309 {
8310 AssignEpsilon ((GetEpsilon (s->expr->followinfo)) != pge_unknown, s->followinfo, GetEpsilon (s->expr->followinfo));
8311 }
8312 CalcEpsilonExpression (s->expr);
8313 }
8314}
8315
8316
8317/*
8318 CalcEpsilonProduction -
8319*/
8320
8321static void CalcEpsilonProduction (pge_ProductionDesc p)
8322{
8323 if (p != NULL)
8324 {
8325 /*
8326 IF p^.statement^.ident^.name=MakeKey('DefinitionModule')
8327 THEN
8328 stop
8329 END ;
8330 */
8331 if (Debugging)
8332 {
8333 NameKey_WriteKey (p->statement->ident->name);
8334 StrIO_WriteString ((const char *) " calculating epsilon", 21);
8335 StrIO_WriteLn ();
8336 }
8337 AssignEpsilon ((GetEpsilon (p->statement->followinfo)) != pge_unknown, p->followinfo, GetEpsilon (p->statement->followinfo));
8338 CalcEpsilonStatement (p->statement);
8339 }
8340}
8341
8342
8343/*
8344 CalcReachEndFactor -
8345*/
8346
8347static pge_TraverseResult CalcReachEndFactor (pge_FactorDesc f)
8348{
8349 pge_TraverseResult canreachend;
8350 pge_TraverseResult result;
8351
8352 if (f == NULL)
8353 {
8354 return pge_true; /* we have reached the end of this factor list */
8355 }
8356 else
8357 {
8358 /* we need to traverse all factors even if we can short cut the answer to this list of factors */
8359 result = CalcReachEndFactor (f->next);
8360 switch (f->type)
8361 {
8362 case pge_id:
8363 if (f->ident->definition == NULL)
8364 {
8365 WarnError1 ((const char *) "definition for %s is absent (assuming epsilon is false for this production)", 75, f->ident->name);
8366 result = pge_false;
8367 }
8368 else if (result != pge_false)
8369 {
8370 /* avoid dangling else. */
8371 switch (GetReachEnd (f->ident->definition->followinfo))
8372 {
8373 case pge_false:
8374 result = pge_false;
8375 break;
8376
8377 case pge_true:
8378 break;
8379
8380 case pge_unknown:
8381 result = pge_unknown;
8382 break;
8383
8384
8385 default:
8386 break;
8387 }
8388 }
8389 break;
8390
8391 case pge_lit:
8392 result = pge_false;
8393 break;
8394
8395 case pge_sub:
8396 CalcReachEndExpression (f->expr);
8397 if ((f->expr != NULL) && (result == pge_true))
8398 {
8399 result = GetReachEnd (f->expr->followinfo);
8400 }
8401 break;
8402
8403 case pge_mult:
8404 case pge_opt:
8405 if (f->expr != NULL)
8406 {
8407 /* not interested in the result as expression is optional */
8408 CalcReachEndExpression (f->expr);
8409 }
8410 break;
8411
8412 case pge_m2:
8413 break;
8414
8415
8416 default:
8417 break;
8418 }
8419 AssignReachEnd (result != pge_unknown, f->followinfo, result);
8420 return result;
8421 }
8422 /* static analysis guarentees a RETURN statement will be used before here. */
8423 __builtin_unreachable ();
8424}
8425
8426
8427/*
8428 CalcReachEndTerm -
8429*/
8430
8431static pge_TraverseResult CalcReachEndTerm (pge_TermDesc t)
8432{
8433 pge_TraverseResult canreachend;
8434 pge_TraverseResult result;
8435
8436 if (t != NULL)
8437 {
8438 canreachend = pge_false;
8439 while (t != NULL)
8440 {
8441 result = CalcReachEndFactor (t->factor);
8442 AssignReachEnd (result != pge_unknown, t->followinfo, result);
8443 switch (result)
8444 {
8445 case pge_true:
8446 canreachend = pge_true;
8447 break;
8448
8449 case pge_false:
8450 break;
8451
8452 case pge_unknown:
8453 if (canreachend == pge_false)
8454 {
8455 canreachend = pge_unknown;
8456 }
8457 break;
8458
8459
8460 default:
8461 break;
8462 }
8463 t = t->next; /* { '|' Term } */
8464 }
8465 return canreachend;
8466 }
8467 /* static analysis guarentees a RETURN statement will be used before here. */
8468 __builtin_unreachable ();
8469}
8470
8471
8472/*
8473 CalcReachEndExpression -
8474*/
8475
8476static void CalcReachEndExpression (pge_ExpressionDesc e)
8477{
8478 pge_TraverseResult result;
8479
8480 if (e == NULL)
8481 {} /* empty. */
8482 else
8483 {
8484 /* no expression, thus reached the end of this sentance */
8485 result = CalcReachEndTerm (e->term);
8486 AssignReachEnd (result != pge_unknown, e->followinfo, result);
8487 }
8488}
8489
8490
8491/*
8492 CalcReachEndStatement -
8493*/
8494
8495static void CalcReachEndStatement (pge_StatementDesc s)
8496{
8497 if (s != NULL)
8498 {
8499 if (s->expr != NULL)
8500 {
8501 CalcReachEndExpression (s->expr);
8502 AssignReachEnd ((GetReachEnd (s->expr->followinfo)) != pge_unknown, s->followinfo, GetReachEnd (s->expr->followinfo));
8503 }
8504 }
8505}
8506
8507
8508/*
8509 CalcReachEndStatement -
8510*/
8511
8512static void stop (void)
8513{
8514}
8515
8516
8517/*
8518 CalcReachEndProduction -
8519*/
8520
8521static void CalcReachEndProduction (pge_ProductionDesc p)
8522{
8523 if (p != NULL)
8524 {
8525 CalcReachEndStatement (p->statement);
8526 if ((GetReachEnd (p->followinfo)) != pge_unknown)
8527 {
8528 if (Debugging)
8529 {
8530 StrIO_WriteString ((const char *) "already calculated reach end for: ", 34);
8531 NameKey_WriteKey (p->statement->ident->name);
8532 StrIO_WriteString ((const char *) " its value is ", 14);
8533 if ((GetReachEnd (p->followinfo)) == pge_true)
8534 {
8535 StrIO_WriteString ((const char *) "reachable", 9);
8536 }
8537 else
8538 {
8539 StrIO_WriteString ((const char *) "non reachable", 13);
8540 }
8541 StrIO_WriteLn ();
8542 }
8543 }
8544 AssignReachEnd ((GetReachEnd (p->statement->followinfo)) != pge_unknown, p->followinfo, GetReachEnd (p->statement->followinfo));
8545 }
8546}
8547
8548
8549/*
8550 EmptyFactor -
8551*/
8552
8553static unsigned int EmptyFactor (pge_FactorDesc f)
8554{
8555 while (f != NULL)
8556 {
8557 switch (f->type)
8558 {
8559 case pge_id:
8560 if (! (EmptyProduction (f->ident->definition)))
8561 {
8562 return FALSE;
8563 }
8564 break;
8565
8566 case pge_lit:
8567 return FALSE;
8568 break;
8569
8570 case pge_sub:
8571 if (! (EmptyExpression (f->expr)))
8572 {
8573 return FALSE;
8574 }
8575 break;
8576
8577 case pge_opt:
8578 case pge_mult:
8579 return TRUE;
8580 break;
8581
8582 case pge_m2:
8583 break;
8584
8585
8586 default:
8587 break;
8588 }
8589 f = f->next;
8590 }
8591 return TRUE;
8592 /* static analysis guarentees a RETURN statement will be used before here. */
8593 __builtin_unreachable ();
8594}
8595
8596
8597/*
8598 EmptyTerm - returns TRUE if the term maybe empty.
8599*/
8600
8601static unsigned int EmptyTerm (pge_TermDesc t)
8602{
8603 while (t != NULL)
8604 {
8605 if (EmptyFactor (t->factor))
8606 {
8607 return TRUE;
8608 }
8609 else
8610 {
8611 t = t->next;
8612 }
8613 }
8614 return FALSE;
8615 /* static analysis guarentees a RETURN statement will be used before here. */
8616 __builtin_unreachable ();
8617}
8618
8619
8620/*
8621 EmptyExpression -
8622*/
8623
8624static unsigned int EmptyExpression (pge_ExpressionDesc e)
8625{
8626 if (e == NULL)
8627 {
8628 return TRUE;
8629 }
8630 else
8631 {
8632 return EmptyTerm (e->term);
8633 }
8634 /* static analysis guarentees a RETURN statement will be used before here. */
8635 __builtin_unreachable ();
8636}
8637
8638
8639/*
8640 EmptyStatement - returns TRUE if statement, s, is empty.
8641*/
8642
8643static unsigned int EmptyStatement (pge_StatementDesc s)
8644{
8645 if (s == NULL)
8646 {
8647 return TRUE;
8648 }
8649 else
8650 {
8651 return EmptyExpression (s->expr);
8652 }
8653 /* static analysis guarentees a RETURN statement will be used before here. */
8654 __builtin_unreachable ();
8655}
8656
8657
8658/*
8659 EmptyProduction - returns if production, p, maybe empty.
8660*/
8661
8662static unsigned int EmptyProduction (pge_ProductionDesc p)
8663{
8664 if (p == NULL)
8665 {
8666 PushBackInput_WarnError ((const char *) "unknown production", 18);
8667 return TRUE;
8668 }
8669 else if (p->firstsolved && (p->first != NULL))
8670 {
8671 /* avoid dangling else. */
8672 /* predefined but first set to something - thus not empty */
8673 return FALSE;
8674 }
8675 else
8676 {
8677 /* avoid dangling else. */
8678 return EmptyStatement (p->statement);
8679 }
8680 /* static analysis guarentees a RETURN statement will be used before here. */
8681 __builtin_unreachable ();
8682}
8683
8684
8685/*
8686 EmitFDLNotice -
8687*/
8688
8689static void EmitFDLNotice (void)
8690{
83ffe9cd 8691 Output_WriteString ((const char *) "@c Copyright (C) 2000-2023 Free Software Foundation, Inc.", 57);
1eee94d3
GM
8692 Output_WriteLn ();
8693 Output_WriteLn ();
8694 Output_WriteString ((const char *) "@c This file is part of GCC.", 28);
8695 Output_WriteLn ();
8696 Output_WriteString ((const char *) "@c Permission is granted to copy, distribute and/or modify this document", 72);
8697 Output_WriteLn ();
8698 Output_WriteString ((const char *) "@c under the terms of the GNU Free Documentation License, Version 1.2 or", 72);
8699 Output_WriteLn ();
8700 Output_WriteString ((const char *) "@c any later version published by the Free Software Foundation.", 63);
8701 Output_WriteLn ();
8702}
8703
8704
8705/*
8706 EmitRules - generates the BNF rules.
8707*/
8708
8709static void EmitRules (void)
8710{
8711 if (Texinfo && FreeDocLicense)
8712 {
8713 EmitFDLNotice ();
8714 }
8715 ForeachRuleDo ((pge_DoProcedure) {(pge_DoProcedure_t) EmitRule});
8716}
8717
8718
8719/*
8720 DescribeElement -
8721*/
8722
8723static void DescribeElement (unsigned int name)
8724{
8725 NameKey_Name lit;
8726
8727 if (InitialElement)
8728 {
8729 InitialElement = FALSE;
8730 }
8731 else
8732 {
8733 Output_WriteString ((const char *) " |", 2);
8734 }
8735 Output_WriteLn ();
8736 Indent = 3;
8737 IndentString ((const char *) "", 0);
8738 Output_WriteKey (name);
8739 Output_WriteString ((const char *) ": ", 2);
8740 lit = static_cast<NameKey_Name> (SymbolKey_GetSymKey (ReverseAliases, name));
8741 if ((NameKey_MakeKey ((const char *) "\"", 1)) == lit)
8742 {
8743 Output_WriteString ((const char *) "str := ConCat(ConCatChar(ConCatChar(InitString(\"syntax error, found ", 68);
8744 Output_Write ('\'');
8745 Output_WriteString ((const char *) "\"), ", 4);
8746 Output_Write ('\'');
8747 Output_Write ('"');
8748 Output_Write ('\'');
8749 Output_WriteString ((const char *) "), ", 3);
8750 Output_Write ('"');
8751 Output_Write ('\'');
8752 Output_Write ('"');
8753 Output_WriteString ((const char *) "), Mark(str))", 13);
8754 }
8755 else if ((NameKey_MakeKey ((const char *) "'", 1)) == lit)
8756 {
8757 /* avoid dangling else. */
8758 Output_WriteString ((const char *) "str := ConCat(ConCatChar(ConCatChar(InitString('syntax error, found ", 68);
8759 Output_Write ('"');
8760 Output_WriteString ((const char *) "'), ", 4);
8761 Output_Write ('"');
8762 Output_Write ('\'');
8763 Output_Write ('"');
8764 Output_WriteString ((const char *) "), ", 3);
8765 Output_Write ('\'');
8766 Output_Write ('"');
8767 Output_Write ('\'');
8768 Output_WriteString ((const char *) "), Mark(str))", 13);
8769 }
8770 else
8771 {
8772 /* avoid dangling else. */
8773 Output_WriteString ((const char *) "str := ConCat(InitString(", 25);
8774 Output_Write ('"');
8775 Output_WriteString ((const char *) "syntax error, found ", 20);
8776 KeyWord (lit);
8777 Output_WriteString ((const char *) "\"), Mark(str))", 14);
8778 }
8779}
8780
8781
8782/*
8783 EmitInTestStop - construct a test for stop element, name.
8784*/
8785
8786static void EmitInTestStop (NameKey_Name name)
8787{
8788 unsigned int i;
8789 unsigned int value;
8790
8791 if (LargestValue <= MaxElementsInSet)
8792 {
8793 Output_WriteKey (name);
8794 Output_WriteString ((const char *) " IN stopset", 11);
8795 ParametersUsed |= (1 << (0 ));
8796 }
8797 else
8798 {
8799 value = static_cast<unsigned int> (SymbolKey_GetSymKey (Values, name));
8800 i = value / MaxElementsInSet;
8801 Output_WriteKey (name);
8802 Output_WriteString ((const char *) " IN stopset", 11);
8803 Output_WriteCard (i, 0);
8804 ParametersUsed |= (1 << (i ));
8805 }
8806}
8807
8808
8809/*
8810 DescribeStopElement -
8811*/
8812
8813static void DescribeStopElement (unsigned int name)
8814{
8815 NameKey_Name lit;
8816
8817 Indent = 3;
8818 IndentString ((const char *) "IF ", 3);
8819 EmitInTestStop (name);
8820 Output_WriteLn ();
8821 IndentString ((const char *) "THEN", 4);
8822 Output_WriteLn ();
8823 Indent = 6;
8824 lit = static_cast<NameKey_Name> (SymbolKey_GetSymKey (ReverseAliases, name));
8825 if ((lit == NameKey_NulName) || (lit == (NameKey_MakeKey ((const char *) "", 0))))
8826 {
8827 IndentString ((const char *) "(* ", 3);
8828 Output_WriteKey (name);
8829 Output_WriteString ((const char *) " has no token name (needed to generate error messages) *)", 57);
8830 }
8831 else if ((NameKey_MakeKey ((const char *) "'", 1)) == lit)
8832 {
8833 /* avoid dangling else. */
8834 IndentString ((const char *) "message := ConCatChar(ConCatChar(ConCatChar(ConCatChar(ConCatChar(message, ", 75);
8835 Output_WriteString ((const char *) "' '), ", 6);
8836 Output_Write ('\'');
8837 Output_Write ('"');
8838 Output_WriteString ((const char *) "'), ", 4);
8839 Output_Write ('"');
8840 Output_Write ('\'');
8841 Output_WriteString ((const char *) "\"), ", 4);
8842 Output_Write ('\'');
8843 Output_Write ('"');
8844 Output_WriteString ((const char *) "'), ',') ; INC(n) ; ", 20);
8845 }
8846 else if ((NameKey_MakeKey ((const char *) "\"", 1)) == lit)
8847 {
8848 /* avoid dangling else. */
8849 IndentString ((const char *) "message := ConCatChar(ConCatChar(ConCatChar(ConCatChar(ConCatChar(message, ", 75);
8850 Output_WriteString ((const char *) "\" \"), ", 6);
8851 Output_Write ('"');
8852 Output_Write ('`');
8853 Output_WriteString ((const char *) "\"), ", 4);
8854 Output_Write ('\'');
8855 Output_Write ('"');
8856 Output_WriteString ((const char *) "'), ", 4);
8857 Output_Write ('"');
8858 Output_Write ('\'');
8859 Output_WriteString ((const char *) "\"), \",\") ; INC(n) ; ", 20);
8860 }
8861 else
8862 {
8863 /* avoid dangling else. */
8864 IndentString ((const char *) "message := ConCat(ConCatChar(message, ' ", 40);
8865 Output_WriteString ((const char *) "'), ", 4);
8866 Output_WriteString ((const char *) "Mark(InitString(\"", 17);
8867 KeyWord (lit);
8868 Output_Write ('"');
8869 Output_WriteString ((const char *) "))) ; INC(n)", 12);
8870 }
8871 Output_WriteLn ();
8872 Indent = 3;
8873 IndentString ((const char *) "END ;", 5);
8874 Output_WriteLn ();
8875}
8876
8877
8878/*
8879 EmitDescribeStop -
8880*/
8881
8882static void EmitDescribeStop (void)
8883{
8884 DynamicStrings_String s;
8885
8886 Output_WriteLn ();
8887 Indent = 0;
8888 IndentString ((const char *) "(*", 2);
8889 Indent = 3;
8890 Output_WriteLn ();
8891 IndentString ((const char *) "DescribeStop - issues a message explaining what tokens were expected", 68);
8892 Output_WriteLn ();
8893 Output_WriteString ((const char *) "*)", 2);
8894 Output_WriteLn ();
8895 Output_WriteLn ();
8896 Indent = 0;
8897 IndentString ((const char *) "PROCEDURE DescribeStop (", 24);
8898 ParametersUsed = (unsigned int) 0;
8899 Output_StartBuffer ();
8900 Output_WriteString ((const char *) ") : String ;", 12);
8901 Output_WriteLn ();
8902 IndentString ((const char *) "VAR", 3);
8903 Output_WriteLn ();
8904 Indent = 3;
8905 IndentString ((const char *) "n : CARDINAL ;", 19);
8906 Output_WriteLn ();
8907 IndentString ((const char *) "str,", 4);
8908 Output_WriteLn ();
8909 IndentString ((const char *) "message: String ;", 17);
8910 Output_WriteLn ();
8911 Indent = 0;
8912 IndentString ((const char *) "BEGIN", 5);
8913 Output_WriteLn ();
8914 Indent = 3;
8915 IndentString ((const char *) "n := 0 ;", 8);
8916 Output_WriteLn ();
8917 IndentString ((const char *) "message := InitString('') ;", 27);
8918 Output_WriteLn ();
8919 SymbolKey_ForeachNodeDo (Aliases, (SymbolKey_PerformOperation) {(SymbolKey_PerformOperation_t) DescribeStopElement});
8920 Output_WriteLn ();
8921 Indent = 3;
8922 IndentString ((const char *) "IF n=0", 6);
8923 Output_WriteLn ();
8924 IndentString ((const char *) "THEN", 4);
8925 Output_WriteLn ();
8926 Indent = 6;
8927 IndentString ((const char *) "str := InitString(' syntax error') ; ", 37);
8928 Output_WriteLn ();
8929 IndentString ((const char *) "message := KillString(message) ; ", 33);
8930 Output_WriteLn ();
8931 Indent = 3;
8932 IndentString ((const char *) "ELSIF n=1", 9);
8933 Output_WriteLn ();
8934 IndentString ((const char *) "THEN", 4);
8935 Output_WriteLn ();
8936 Indent = 6;
8937 IndentString ((const char *) "str := ConCat(message, Mark(InitString(' missing '))) ;", 55);
8938 Output_WriteLn ();
8939 Indent = 3;
8940 IndentString ((const char *) "ELSE", 4);
8941 Output_WriteLn ();
8942 Indent = 6;
8943 IndentString ((const char *) "str := ConCat(InitString(' expecting one of'), message) ;", 57);
8944 Output_WriteLn ();
8945 IndentString ((const char *) "message := KillString(message) ;", 32);
8946 Output_WriteLn ();
8947 Indent = 3;
8948 IndentString ((const char *) "END ;", 5);
8949 Output_WriteLn ();
8950 IndentString ((const char *) "RETURN( str )", 13);
8951 Output_WriteLn ();
8952 Indent = 0;
8953 IndentString ((const char *) "END DescribeStop ;", 18);
8954 Output_WriteLn ();
8955 Output_WriteLn ();
8956 s = Output_EndBuffer ();
8957 EmitStopParameters (TRUE);
8958 Output_KillWriteS (s);
8959}
8960
8961
8962/*
8963 EmitDescribeError -
8964*/
8965
8966static void EmitDescribeError (void)
8967{
8968 Output_WriteLn ();
8969 Indent = 0;
8970 IndentString ((const char *) "(*", 2);
8971 Output_WriteLn ();
8972 Indent = 3;
8973 IndentString ((const char *) "DescribeError - issues a message explaining what tokens were expected", 69);
8974 Output_WriteLn ();
8975 Indent = 0;
8976 IndentString ((const char *) "*)", 2);
8977 Output_WriteLn ();
8978 Output_WriteLn ();
8979 IndentString ((const char *) "PROCEDURE DescribeError ;", 25);
8980 Output_WriteLn ();
8981 IndentString ((const char *) "VAR", 3);
8982 Output_WriteLn ();
8983 Indent = 3;
8984 IndentString ((const char *) "str: String ;", 13);
8985 Output_WriteLn ();
8986 Indent = 0;
8987 IndentString ((const char *) "BEGIN", 5);
8988 Output_WriteLn ();
8989 Indent = 3;
8990 IndentString ((const char *) "str := InitString('') ;", 23);
8991 Output_WriteLn ();
8992 /* was
8993 IndentString('str := DescribeStop(') ; EmitStopParameters(FALSE) ; Output.WriteString(') ;') ; Output.WriteLn ;
8994 */
8995 IndentString ((const char *) "CASE ", 5);
8996 WriteGetTokenType ();
8997 Output_WriteString ((const char *) " OF", 3);
8998 NewLine (3);
8999 InitialElement = TRUE;
9000 SymbolKey_ForeachNodeDo (Aliases, (SymbolKey_PerformOperation) {(SymbolKey_PerformOperation_t) DescribeElement});
9001 Output_WriteLn ();
9002 Indent = 3;
9003 IndentString ((const char *) "ELSE", 4);
9004 Output_WriteLn ();
9005 IndentString ((const char *) "END ;", 5);
9006 Output_WriteLn ();
9007 IndentString ((const char *) "", 0);
9008 Output_WriteKey (ErrorProcString);
9009 Output_WriteString ((const char *) "(str) ;", 7);
9010 Output_WriteLn ();
9011 Indent = 0;
9012 IndentString ((const char *) "END DescribeError ;", 19);
9013 Output_WriteLn ();
9014}
9015
9016
9017/*
9018 EmitSetTypes - write out the set types used during error recovery
9019*/
9020
9021static void EmitSetTypes (void)
9022{
9023 unsigned int i;
9024 unsigned int j;
9025 unsigned int m;
9026 unsigned int n;
9027
9028 Output_WriteString ((const char *) "(*", 2);
9029 NewLine (3);
9030 Output_WriteString ((const char *) "expecting token set defined as an enumerated type", 49);
9031 NewLine (3);
9032 Output_WriteString ((const char *) "(", 1);
9033 i = 0;
9034 while (i < LargestValue)
9035 {
9036 Output_WriteKey (SymbolKey_GetSymKey (ReverseValues, (unsigned int ) (i)));
9037 i += 1;
9038 if (i < LargestValue)
9039 {
9040 Output_WriteString ((const char *) ", ", 2);
9041 }
9042 }
9043 Output_WriteString ((const char *) ") ;", 3);
9044 NewLine (0);
9045 Output_WriteString ((const char *) "*)", 2);
9046 NewLine (0);
9047 Output_WriteString ((const char *) "TYPE", 4);
9048 NewLine (3);
9049 if (LargestValue > MaxElementsInSet)
9050 {
9051 i = 0;
9052 n = LargestValue / MaxElementsInSet;
9053 while (i <= n)
9054 {
9055 j = i*MaxElementsInSet;
9056 if (LargestValue < (((i+1)*MaxElementsInSet)-1))
9057 {
9058 m = LargestValue-1;
9059 }
9060 else
9061 {
9062 m = ((i+1)*MaxElementsInSet)-1;
9063 }
9064 Output_WriteString ((const char *) "stop", 4);
9065 Output_WriteCard (i, 0);
9066 Output_WriteString ((const char *) " = [", 4);
9067 Output_WriteKey (SymbolKey_GetSymKey (ReverseValues, (unsigned int ) (j)));
9068 Output_WriteString ((const char *) "..", 2);
9069 Output_WriteKey (SymbolKey_GetSymKey (ReverseValues, (unsigned int ) (m)));
9070 Output_WriteString ((const char *) "] ;", 3);
9071 NewLine (3);
9072 Output_WriteString ((const char *) "SetOfStop", 9);
9073 Output_WriteCard (i, 0);
9074 Output_WriteString ((const char *) " = SET OF stop", 14);
9075 Output_WriteCard (i, 0);
9076 Output_WriteString ((const char *) " ;", 2);
9077 NewLine (3);
9078 i += 1;
9079 }
9080 }
9081 else
9082 {
9083 Output_WriteString ((const char *) "SetOfStop", 9);
9084 Output_WriteString ((const char *) " = SET OF [", 11);
9085 Output_WriteKey (SymbolKey_GetSymKey (ReverseValues, (unsigned int ) (0)));
9086 Output_WriteString ((const char *) "..", 2);
9087 Output_WriteKey (SymbolKey_GetSymKey (ReverseValues, (unsigned int ) (LargestValue-1)));
9088 Output_WriteString ((const char *) "] ;", 3);
9089 }
9090 NewLine (0);
9091}
9092
9093
9094/*
9095 EmitSupport - generates the support routines.
9096*/
9097
9098static void EmitSupport (void)
9099{
9100 if (ErrorRecovery)
9101 {
9102 EmitSetTypes ();
9103 EmitDescribeStop ();
9104 EmitDescribeError ();
9105 }
9106}
9107
9108
9109/*
9110 DisposeSetDesc - dispose of the set list, s.
9111*/
9112
9113static void DisposeSetDesc (pge_SetDesc *s)
9114{
9115 pge_SetDesc h;
9116 pge_SetDesc n;
9117
9118 if ((*s) != NULL)
9119 {
9120 h = (*s);
9121 n = (*s)->next;
9122 do {
9123 Storage_DEALLOCATE ((void **) &h, sizeof (pge__T7));
9124 h = n;
9125 if (n != NULL)
9126 {
9127 n = n->next;
9128 }
9129 } while (! (h == NULL));
9130 (*s) = NULL;
9131 }
9132}
9133
9134
9135/*
9136 OptionalFactor -
9137*/
9138
9139static unsigned int OptionalFactor (pge_FactorDesc f)
9140{
9141 while (f != NULL)
9142 {
9143 switch (f->type)
9144 {
9145 case pge_id:
9146 break;
9147
9148 case pge_lit:
9149 break;
9150
9151 case pge_sub:
9152 case pge_opt:
9153 case pge_mult:
9154 if (OptionalExpression (f->expr))
9155 {
9156 return TRUE;
9157 }
9158 break;
9159
9160 case pge_m2:
9161 break;
9162
9163
9164 default:
9165 break;
9166 }
9167 f = f->next;
9168 }
9169 return FALSE;
9170 /* static analysis guarentees a RETURN statement will be used before here. */
9171 __builtin_unreachable ();
9172}
9173
9174
9175/*
9176 OptionalTerm - returns TRUE if the term maybe empty.
9177*/
9178
9179static unsigned int OptionalTerm (pge_TermDesc t)
9180{
9181 pge_TermDesc u;
9182 pge_TermDesc v;
9183 pge_SetDesc tov;
9184 pge_SetDesc tou;
9185
9186 u = t;
9187 while (u != NULL)
9188 {
9189 if (OptionalFactor (u->factor))
9190 {
9191 return TRUE;
9192 }
9193 v = t;
9194 tou = NULL;
9195 CalcFirstFactor (u->factor, NULL, &tou);
9196 while (v != NULL)
9197 {
9198 if (v != u)
9199 {
9200 tov = NULL;
9201 CalcFirstFactor (v->factor, NULL, &tov);
9202 if (IntersectionIsNil (tov, tou))
9203 {
9204 DisposeSetDesc (&tov);
9205 }
9206 else
9207 {
9208 StrIO_WriteString ((const char *) "problem with two first sets. Set 1: ", 36);
9209 EmitSet (tou, static_cast<unsigned int> (0), static_cast<unsigned int> (0));
9210 StrIO_WriteLn ();
9211 StrIO_WriteString ((const char *) " Set 2: ", 36);
9212 EmitSet (tov, static_cast<unsigned int> (0), static_cast<unsigned int> (0));
9213 StrIO_WriteLn ();
9214 DisposeSetDesc (&tou);
9215 DisposeSetDesc (&tov);
9216 return TRUE;
9217 }
9218 }
9219 v = v->next;
9220 }
9221 DisposeSetDesc (&tou);
9222 u = u->next;
9223 }
9224 return FALSE;
9225 /* static analysis guarentees a RETURN statement will be used before here. */
9226 __builtin_unreachable ();
9227}
9228
9229
9230/*
9231 OptionalExpression -
9232*/
9233
9234static unsigned int OptionalExpression (pge_ExpressionDesc e)
9235{
9236 if (e == NULL)
9237 {
9238 return FALSE;
9239 }
9240 else
9241 {
9242 return OptionalTerm (e->term);
9243 }
9244 /* static analysis guarentees a RETURN statement will be used before here. */
9245 __builtin_unreachable ();
9246}
9247
9248
9249/*
9250 OptionalStatement - returns FALSE if statement, s, does not have a optional ambiguity.
9251*/
9252
9253static unsigned int OptionalStatement (pge_StatementDesc s)
9254{
9255 if (s == NULL)
9256 {
9257 return FALSE;
9258 }
9259 else
9260 {
9261 return OptionalExpression (s->expr);
9262 }
9263 /* static analysis guarentees a RETURN statement will be used before here. */
9264 __builtin_unreachable ();
9265}
9266
9267
9268/*
9269 OptionalProduction -
9270*/
9271
9272static unsigned int OptionalProduction (pge_ProductionDesc p)
9273{
9274 if (p == NULL)
9275 {
9276 return FALSE;
9277 }
9278 else
9279 {
9280 return OptionalStatement (p->statement);
9281 }
9282 /* static analysis guarentees a RETURN statement will be used before here. */
9283 __builtin_unreachable ();
9284}
9285
9286
9287/*
9288 CheckFirstFollow -
9289*/
9290
9291static unsigned int CheckFirstFollow (pge_FactorDesc f, pge_FactorDesc after)
9292{
9293 pge_SetDesc first;
9294 pge_SetDesc follow;
9295
9296 first = NULL;
9297 CalcFirstFactor (f, NULL, &first);
9298 follow = NULL;
9299 follow = GetFollow (f->followinfo);
9300 if (IntersectionIsNil (first, follow))
9301 {
9302 DisposeSetDesc (&first);
9303 DisposeSetDesc (&follow);
9304 return FALSE;
9305 }
9306 else
9307 {
9308 PrettyCommentFactor (f, 3);
9309 NewLine (3);
9310 StrIO_WriteString ((const char *) "first: ", 7);
9311 EmitSet (first, static_cast<unsigned int> (0), static_cast<unsigned int> (0));
9312 NewLine (3);
9313 StrIO_WriteString ((const char *) "follow: ", 8);
9314 EmitSet (follow, static_cast<unsigned int> (0), static_cast<unsigned int> (0));
9315 NewLine (3);
9316 DisposeSetDesc (&first);
9317 DisposeSetDesc (&follow);
9318 return TRUE;
9319 }
9320 /* static analysis guarentees a RETURN statement will be used before here. */
9321 __builtin_unreachable ();
9322}
9323
9324
9325/*
9326 ConstrainedEmptyFactor -
9327*/
9328
9329static unsigned int ConstrainedEmptyFactor (pge_FactorDesc f)
9330{
9331 while (f != NULL)
9332 {
9333 switch (f->type)
9334 {
9335 case pge_id:
9336 break;
9337
9338 case pge_lit:
9339 break;
9340
9341 case pge_sub:
9342 case pge_opt:
9343 case pge_mult:
9344 if (ConstrainedEmptyExpression (f->expr))
9345 {
9346 return TRUE;
9347 }
9348 break;
9349
9350 case pge_m2:
9351 break;
9352
9353
9354 default:
9355 break;
9356 }
9357 if (((f->type != pge_m2) && (EmptyFactor (f))) && (CheckFirstFollow (f, f->next)))
9358 {
9359 return TRUE;
9360 }
9361 f = f->next;
9362 }
9363 return FALSE;
9364 /* static analysis guarentees a RETURN statement will be used before here. */
9365 __builtin_unreachable ();
9366}
9367
9368
9369/*
9370 ConstrainedEmptyTerm - returns TRUE if the term maybe empty.
9371*/
9372
9373static unsigned int ConstrainedEmptyTerm (pge_TermDesc t)
9374{
9375 pge_SetDesc first;
9376 pge_SetDesc follow;
9377
9378 while (t != NULL)
9379 {
9380 if (ConstrainedEmptyFactor (t->factor))
9381 {
9382 return TRUE;
9383 }
9384 else if (((t->factor->type != pge_m2) && (EmptyFactor (t->factor))) && (CheckFirstFollow (t->factor, t->factor->next)))
9385 {
9386 /* avoid dangling else. */
9387 return TRUE;
9388 }
9389 t = t->next;
9390 }
9391 return FALSE;
9392 /* static analysis guarentees a RETURN statement will be used before here. */
9393 __builtin_unreachable ();
9394}
9395
9396
9397/*
9398 ConstrainedEmptyExpression -
9399*/
9400
9401static unsigned int ConstrainedEmptyExpression (pge_ExpressionDesc e)
9402{
9403 if (e == NULL)
9404 {
9405 return FALSE;
9406 }
9407 else
9408 {
9409 return ConstrainedEmptyTerm (e->term);
9410 }
9411 /* static analysis guarentees a RETURN statement will be used before here. */
9412 __builtin_unreachable ();
9413}
9414
9415
9416/*
9417 ConstrainedEmptyStatement - returns FALSE if statement, s, does not have a optional ambiguity.
9418*/
9419
9420static unsigned int ConstrainedEmptyStatement (pge_StatementDesc s)
9421{
9422 if (s == NULL)
9423 {
9424 return FALSE;
9425 }
9426 else
9427 {
9428 return ConstrainedEmptyExpression (s->expr);
9429 }
9430 /* static analysis guarentees a RETURN statement will be used before here. */
9431 __builtin_unreachable ();
9432}
9433
9434
9435/*
9436 ConstrainedEmptyProduction - returns TRUE if a problem exists with, p.
9437*/
9438
9439static unsigned int ConstrainedEmptyProduction (pge_ProductionDesc p)
9440{
9441 if (p == NULL)
9442 {
9443 return FALSE;
9444 }
9445 else
9446 {
9447 return ConstrainedEmptyStatement (p->statement);
9448 }
9449 /* static analysis guarentees a RETURN statement will be used before here. */
9450 __builtin_unreachable ();
9451}
9452
9453
9454/*
9455 TestForLALR1 -
9456*/
9457
9458static void TestForLALR1 (pge_ProductionDesc p)
9459{
9460 if (OptionalProduction (p))
9461 {
9462 WarnError1 ((const char *) "production %s has two optional sentances using | which both have the same start symbols", 87, p->statement->ident->name);
9463 WasNoError = FALSE;
9464 PrettyCommentProduction (p);
9465 }
9466}
9467
9468
9469/*
9470 DoEpsilon - runs the epsilon interrelated rules
9471*/
9472
9473static void DoEpsilon (pge_ProductionDesc p)
9474{
9475 CalcEpsilonProduction (p);
9476 CalcReachEndProduction (p);
9477}
9478
9479
9480/*
9481 CheckComplete - checks that production, p, is complete.
9482*/
9483
9484static void CheckComplete (pge_ProductionDesc p)
9485{
9486 if ((GetReachEnd (p->followinfo)) == pge_unknown)
9487 {
9488 PrettyCommentProduction (p);
9489 WarnError1 ((const char *) "cannot determine epsilon, probably a left recursive rule in %s and associated rules (hint rewrite using ebnf and eliminate left recursion)", 138, p->statement->ident->name);
9490 WasNoError = FALSE;
9491 }
9492}
9493
9494
9495/*
9496 PostProcessRules - backpatch the ident to rule definitions and emit comments and code.
9497*/
9498
9499static void PostProcessRules (void)
9500{
9501 ForeachRuleDo ((pge_DoProcedure) {(pge_DoProcedure_t) BackPatchIdentToDefinitions});
9502 if (! WasNoError)
9503 {
9504 M2RTS_HALT (-1);
9505 __builtin_unreachable ();
9506 }
9507 WhileNotCompleteDo ((pge_DoProcedure) {(pge_DoProcedure_t) DoEpsilon});
9508 if (! WasNoError)
9509 {
9510 M2RTS_HALT (-1);
9511 __builtin_unreachable ();
9512 }
9513 ForeachRuleDo ((pge_DoProcedure) {(pge_DoProcedure_t) CheckComplete});
9514 if (! WasNoError)
9515 {
9516 M2RTS_HALT (-1);
9517 __builtin_unreachable ();
9518 }
9519 WhileNotCompleteDo ((pge_DoProcedure) {(pge_DoProcedure_t) CalculateFirstAndFollow});
9520 if (! WasNoError)
9521 {
9522 M2RTS_HALT (-1);
9523 __builtin_unreachable ();
9524 }
9525 ForeachRuleDo ((pge_DoProcedure) {(pge_DoProcedure_t) TestForLALR1});
9526 if (! WasNoError)
9527 {
9528 ForeachRuleDo ((pge_DoProcedure) {(pge_DoProcedure_t) PrettyCommentProduction});
9529 }
9530}
9531
9532
9533/*
9534 DisplayHelp - display a summary help and then exit (0).
9535*/
9536
9537static void DisplayHelp (void)
9538{
9539 StrIO_WriteString ((const char *) "Usage: pge [-l] [-c] [-d] [-e] [-k] [-t] [-k] [-p] [-x] [-f] [-o outputfile] filename", 85);
9540 StrIO_WriteLn ();
9541 StrIO_WriteString ((const char *) " -l suppress file and line source information", 59);
9542 StrIO_WriteLn ();
9543 StrIO_WriteString ((const char *) " -c do not generate any Modula-2 code within the parser rules", 75);
9544 StrIO_WriteLn ();
9545 StrIO_WriteString ((const char *) " -h or --help generate this help message", 44);
9546 StrIO_WriteLn ();
9547 StrIO_WriteString ((const char *) " -e do not generate a parser with error recovery", 62);
9548 StrIO_WriteLn ();
9549 StrIO_WriteString ((const char *) " -k generate keyword errors with GCC formatting directives", 72);
9550 StrIO_WriteLn ();
9551 StrIO_WriteString ((const char *) " -d generate internal debugging information", 57);
9552 StrIO_WriteLn ();
9553 StrIO_WriteString ((const char *) " -p only display the ebnf rules", 45);
9554 StrIO_WriteLn ();
9555 StrIO_WriteString ((const char *) " -t generate texinfo formating for pretty printing (-p)", 69);
9556 StrIO_WriteLn ();
9557 StrIO_WriteString ((const char *) " -x generate sphinx formating for pretty printing (-p)", 68);
9558 StrIO_WriteLn ();
9559 StrIO_WriteString ((const char *) " -f generate GNU Free Documentation header before pretty printing in texinfo", 90);
9560 StrIO_WriteLn ();
9561 StrIO_WriteString ((const char *) " -o write output to filename", 42);
9562 StrIO_WriteLn ();
9563 libc_exit (0);
9564}
9565
9566
9567/*
9568 ParseArgs -
9569*/
9570
9571static void ParseArgs (void)
9572{
9573 unsigned int n;
9574 unsigned int i;
9575
9576 ErrorRecovery = TRUE; /* DefaultRecovery ; */
9577 Debugging = FALSE; /* DefaultRecovery ; */
9578 PrettyPrint = FALSE;
9579 KeywordFormatting = FALSE;
9580 i = 1;
9581 n = Args_Narg ();
9582 while (i < n)
9583 {
9584 if (Args_GetArg ((char *) &ArgName.array[0], MaxFileName, i))
9585 {
9586 /* avoid gcc warning by using compound statement even if not strictly necessary. */
9587 if (StrLib_StrEqual ((const char *) &ArgName.array[0], MaxFileName, (const char *) "-e", 2))
9588 {
9589 ErrorRecovery = FALSE;
9590 }
9591 else if (StrLib_StrEqual ((const char *) &ArgName.array[0], MaxFileName, (const char *) "-d", 2))
9592 {
9593 /* avoid dangling else. */
9594 Debugging = TRUE;
9595 bnflex_SetDebugging (TRUE);
9596 }
9597 else if (StrLib_StrEqual ((const char *) &ArgName.array[0], MaxFileName, (const char *) "-c", 2))
9598 {
9599 /* avoid dangling else. */
9600 EmitCode = FALSE;
9601 }
9602 else if (StrLib_StrEqual ((const char *) &ArgName.array[0], MaxFileName, (const char *) "-k", 2))
9603 {
9604 /* avoid dangling else. */
9605 KeywordFormatting = TRUE;
9606 }
9607 else if (StrLib_StrEqual ((const char *) &ArgName.array[0], MaxFileName, (const char *) "-l", 2))
9608 {
9609 /* avoid dangling else. */
9610 SuppressFileLineTag = TRUE;
9611 }
9612 else if ((StrLib_StrEqual ((const char *) &ArgName.array[0], MaxFileName, (const char *) "-h", 2)) || (StrLib_StrEqual ((const char *) &ArgName.array[0], MaxFileName, (const char *) "--help", 6)))
9613 {
9614 /* avoid dangling else. */
9615 DisplayHelp ();
9616 }
9617 else if (StrLib_StrEqual ((const char *) &ArgName.array[0], MaxFileName, (const char *) "-p", 2))
9618 {
9619 /* avoid dangling else. */
9620 PrettyPrint = TRUE;
9621 }
9622 else if (StrLib_StrEqual ((const char *) &ArgName.array[0], MaxFileName, (const char *) "-t", 2))
9623 {
9624 /* avoid dangling else. */
9625 Texinfo = TRUE;
9626 }
9627 else if (StrLib_StrEqual ((const char *) &ArgName.array[0], MaxFileName, (const char *) "-x", 2))
9628 {
9629 /* avoid dangling else. */
9630 Sphinx = TRUE;
9631 }
9632 else if (StrLib_StrEqual ((const char *) &ArgName.array[0], MaxFileName, (const char *) "-f", 2))
9633 {
9634 /* avoid dangling else. */
9635 FreeDocLicense = TRUE;
9636 }
9637 else if (StrLib_StrEqual ((const char *) &ArgName.array[0], MaxFileName, (const char *) "-o", 2))
9638 {
9639 /* avoid dangling else. */
9640 i += 1;
9641 if (Args_GetArg ((char *) &ArgName.array[0], MaxFileName, i))
9642 {
9643 if (! (Output_Open ((const char *) &ArgName.array[0], MaxFileName)))
9644 {
9645 StrIO_WriteString ((const char *) "cannot open ", 12);
9646 StrIO_WriteString ((const char *) &ArgName.array[0], MaxFileName);
9647 StrIO_WriteString ((const char *) " for writing", 12);
9648 StrIO_WriteLn ();
9649 libc_exit (1);
9650 }
9651 }
9652 }
9653 else if (bnflex_OpenSource ((const char *) &ArgName.array[0], MaxFileName))
9654 {
9655 /* avoid dangling else. */
9656 StrLib_StrCopy ((const char *) &ArgName.array[0], MaxFileName, (char *) &FileName.array[0], MaxFileName);
9657 bnflex_AdvanceToken ();
9658 }
9659 else
9660 {
9661 /* avoid dangling else. */
9662 StrIO_WriteString ((const char *) "cannot open ", 12);
9663 StrIO_WriteString ((const char *) &ArgName.array[0], MaxFileName);
9664 StrIO_WriteString ((const char *) " for reading", 12);
9665 StrIO_WriteLn ();
9666 libc_exit (1);
9667 }
9668 }
9669 i += 1;
9670 }
9671 if (n == 1)
9672 {
9673 DisplayHelp ();
9674 }
9675}
9676
9677
9678/*
9679 Init - initialize the modules data structures
9680*/
9681
9682static void Init (void)
9683{
9684 WasNoError = TRUE;
9685 Texinfo = FALSE;
9686 Sphinx = FALSE;
9687 FreeDocLicense = FALSE;
9688 EmitCode = TRUE;
9689 LargestValue = 0;
9690 HeadProduction = NULL;
9691 CurrentProduction = NULL;
9692 SymbolKey_InitTree (&Aliases);
9693 SymbolKey_InitTree (&ReverseAliases);
9694 SymbolKey_InitTree (&Values);
9695 SymbolKey_InitTree (&ReverseValues);
9696 LastLineNo = 0;
9697 CodePrologue = NULL;
9698 CodeEpilogue = NULL;
9699 CodeDeclaration = NULL;
9700 ErrorProcArray = NameKey_MakeKey ((const char *) "Error", 5);
9701 ErrorProcString = NameKey_MakeKey ((const char *) "ErrorS", 6);
9702 TokenTypeProc = NameKey_MakeKey ((const char *) "GetCurrentTokenType()", 21);
9703 SymIsProc = NameKey_MakeKey ((const char *) "SymIs", 5);
9704 OnLineStart = TRUE;
9705 ParseArgs ();
9706 Main (static_cast<pge_SetOfStop> ((unsigned int) ((1 << (bnflex_eoftok))))); /* this line will be manipulated by sed in buildpg */
9707 if (WasNoError) /* this line will be manipulated by sed in buildpg */
9708 {
9709 PostProcessRules ();
9710 if (WasNoError)
9711 {
9712 /* avoid gcc warning by using compound statement even if not strictly necessary. */
9713 if (Debugging)
9714 {
9715 EmitRules ();
9716 }
9717 else if (PrettyPrint)
9718 {
9719 /* avoid dangling else. */
9720 EmitRules ();
9721 }
9722 else
9723 {
9724 /* avoid dangling else. */
9725 Output_WriteString ((const char *) "(* it is advisable not to edit this file as it was automatically generated from the grammer file ", 97);
9726 Output_WriteString ((const char *) &FileName.array[0], MaxFileName);
9727 Output_WriteString ((const char *) " *)", 3);
9728 Output_WriteLn ();
9729 OnLineStart = FALSE;
9730 EmitFileLineTag (LinePrologue);
9731 BeginningOfLine = TRUE;
9732 WriteCodeHunkList (CodePrologue);
9733 EmitSupport ();
9734 EmitFileLineTag (LineDeclaration);
9735 WriteCodeHunkList (CodeDeclaration);
9736 EmitRules ();
9737 /* code rules */
9738 EmitFileLineTag (LineEpilogue);
9739 WriteCodeHunkList (CodeEpilogue);
9740 }
9741 }
9742 }
9743 Output_Close ();
9744}
9745
9746extern "C" void _M2_pge_init (__attribute__((unused)) int argc,__attribute__((unused)) char *argv[],__attribute__((unused)) char *envp[])
9747{
9748 Init ();
9749}
9750
9751extern "C" void _M2_pge_finish (__attribute__((unused)) int argc,__attribute__((unused)) char *argv[],__attribute__((unused)) char *envp[])
9752{
9753}