/* do not edit automatically generated by mc from pge. */ /* pge.mod master source file of the ebnf parser generator. Copyright (C) 2003-2023 Free Software Foundation, Inc. Contributed by Gaius Mulley . This file is part of GNU Modula-2. GNU Modula-2 is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. GNU Modula-2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Modula-2; see the file COPYING3. If not see . */ #include # if !defined (PROC_D) # define PROC_D typedef void (*PROC_t) (void); typedef struct { PROC_t proc; } PROC; # endif # if !defined (TRUE) # define TRUE (1==1) # endif # if !defined (FALSE) # define FALSE (1==0) # endif #include #include #include # include "GStorage.h" # include "Gmcrts.h" #if defined(__cplusplus) # undef NULL # define NULL 0 #endif # include "GPushBackInput.h" # include "Gbnflex.h" # include "GStrLib.h" # include "GStorage.h" # include "GNameKey.h" # include "GNumberIO.h" # include "GSymbolKey.h" # include "GLists.h" # include "GDynamicStrings.h" # include "GASCII.h" # include "GStrIO.h" # include "GStdIO.h" # include "GDebug.h" # include "GArgs.h" # include "GSYSTEM.h" # include "Glibc.h" # include "GOutput.h" # include "GM2RTS.h" # define MaxCodeHunkLength 8192 # define MaxFileName 8192 # define MaxString 8192 # define DefaultRecovery true # define MaxElementsInSet 32 # define BaseRightLimit 75 # define BaseRightMargin 50 # define BaseNewLine 3 typedef struct pge_termdesc_r pge_termdesc; typedef pge_termdesc *pge_TermDesc; typedef struct pge_DoProcedure_p pge_DoProcedure; typedef unsigned int pge_SetOfStop; typedef struct pge__T1_r pge__T1; typedef pge__T1 *pge_IdentDesc; typedef struct pge__T2_r pge__T2; typedef pge__T2 *pge_ProductionDesc; typedef struct pge__T3_r pge__T3; typedef pge__T3 *pge_StatementDesc; typedef struct pge__T4_r pge__T4; typedef pge__T4 *pge_ExpressionDesc; typedef struct pge__T5_r pge__T5; typedef struct pge__T6_r pge__T6; typedef pge__T6 *pge_FollowDesc; typedef struct pge__T7_r pge__T7; typedef pge__T7 *pge_SetDesc; typedef struct pge__T8_r pge__T8; typedef pge__T8 *pge_CodeDesc; typedef struct pge__T9_r pge__T9; typedef pge__T9 *pge_CodeHunk; typedef struct pge__T10_a pge__T10; typedef struct pge__T11_a pge__T11; typedef enum {pge_idel, pge_tokel, pge_litel} pge_ElementType; typedef enum {pge_m2none, pge_m2if, pge_m2elsif, pge_m2while} pge_m2condition; typedef enum {pge_unknown, pge_true, pge_false} pge_TraverseResult; typedef enum {pge_id, pge_lit, pge_sub, pge_opt, pge_mult, pge_m2} pge_FactorType; typedef pge__T5 *pge_FactorDesc; struct pge_termdesc_r { pge_FactorDesc factor; pge_TermDesc next; pge_FollowDesc followinfo; unsigned int line; }; typedef void (*pge_DoProcedure_t) (pge_ProductionDesc); struct pge_DoProcedure_p { pge_DoProcedure_t proc; }; struct pge__T1_r { pge_ProductionDesc definition; NameKey_Name name; unsigned int line; }; struct pge__T2_r { pge_ProductionDesc next; pge_StatementDesc statement; pge_SetDesc first; bool firstsolved; pge_FollowDesc followinfo; unsigned int line; NameKey_Name description; }; struct pge__T3_r { pge_IdentDesc ident; pge_ExpressionDesc expr; pge_FollowDesc followinfo; unsigned int line; }; struct pge__T4_r { pge_TermDesc term; pge_FollowDesc followinfo; unsigned int line; }; struct pge__T5_r { pge_FollowDesc followinfo; pge_FactorDesc next; unsigned int line; pge_FactorDesc pushed; pge_FactorType type; /* case tag */ union { pge_IdentDesc ident; NameKey_Name string; pge_ExpressionDesc expr; pge_CodeDesc code; }; }; struct pge__T6_r { bool calcfollow; pge_SetDesc follow; pge_TraverseResult reachend; pge_TraverseResult epsilon; unsigned int line; }; struct pge__T7_r { pge_SetDesc next; pge_ElementType type; /* case tag */ union { pge_IdentDesc ident; NameKey_Name string; }; }; struct pge__T8_r { pge_CodeHunk code; unsigned int indent; unsigned int line; }; struct pge__T10_a { char array[MaxCodeHunkLength+1]; }; struct pge__T11_a { char array[MaxFileName+1]; }; struct pge__T9_r { pge__T10 codetext; pge_CodeHunk next; }; static unsigned int LastLineNo; static bool Finished; static bool SuppressFileLineTag; static bool KeywordFormatting; static bool PrettyPrint; static bool EmitCode; static bool Texinfo; static bool Sphinx; static bool FreeDocLicense; static bool Debugging; static bool WasNoError; static unsigned int LinePrologue; static unsigned int LineEpilogue; static unsigned int LineDeclaration; static pge_CodeHunk CodePrologue; static pge_CodeHunk CodeEpilogue; static pge_CodeHunk CodeDeclaration; static pge_ProductionDesc CurrentProduction; static pge_ProductionDesc TailProduction; static pge_ProductionDesc HeadProduction; static pge_ExpressionDesc CurrentExpression; static pge_TermDesc CurrentTerm; static pge_FactorDesc CurrentFactor; static pge_IdentDesc CurrentIdent; static pge_StatementDesc CurrentStatement; static pge_SetDesc CurrentSetDesc; static SymbolKey_SymbolTree ReverseValues; static SymbolKey_SymbolTree Values; static SymbolKey_SymbolTree ReverseAliases; static SymbolKey_SymbolTree Aliases; static NameKey_Name ModuleName; static NameKey_Name LastLiteral; static NameKey_Name LastIdent; static NameKey_Name SymIsProc; static NameKey_Name TokenTypeProc; static NameKey_Name ErrorProcArray; static NameKey_Name ErrorProcString; static pge__T11 ArgName; static pge__T11 FileName; static bool OnLineStart; static bool BeginningOfLine; static unsigned int Indent; static bool EmittedVar; static bool ErrorRecovery; static unsigned int LargestValue; static bool InitialElement; static unsigned int ParametersUsed; /* DescribeStop - issues a message explaining what tokens were expected */ static DynamicStrings_String DescribeStop (pge_SetOfStop stopset); /* DescribeError - issues a message explaining what tokens were expected */ static void DescribeError (void); /* AddEntry - adds an entry into, t, containing [def:value]. */ static void AddEntry (SymbolKey_SymbolTree *t, NameKey_Name def, NameKey_Name value); /* Format1 - converts string, src, into, dest, together with encapsulated entity, n. It only formats the first %s or %d with n. */ static void Format1 (const char *src_, unsigned int _src_high, unsigned int n, char *dest, unsigned int _dest_high); /* WarnError1 - */ static void WarnError1 (const char *a_, unsigned int _a_high, unsigned int n); /* PrettyFollow - */ static void PrettyFollow (const char *start_, unsigned int _start_high, const char *end_, unsigned int _end_high, pge_FollowDesc f); /* NewFollow - creates a new follow descriptor and returns the data structure. */ static pge_FollowDesc NewFollow (void); /* AssignEpsilon - assigns the epsilon value and sets the epsilon to value, providing condition is TRUE. */ static void AssignEpsilon (bool condition, pge_FollowDesc f, pge_TraverseResult value); /* GetEpsilon - returns the value of epsilon */ static pge_TraverseResult GetEpsilon (pge_FollowDesc f); /* AssignReachEnd - assigns the reachend value providing that, condition, is TRUE. */ static void AssignReachEnd (bool condition, pge_FollowDesc f, pge_TraverseResult value); /* GetReachEnd - returns the value of reachend */ static pge_TraverseResult GetReachEnd (pge_FollowDesc f); /* AssignFollow - assigns the follow set and sets the calcfollow to TRUE. */ static void AssignFollow (pge_FollowDesc f, pge_SetDesc s); /* GetFollow - returns the follow set. */ static pge_SetDesc GetFollow (pge_FollowDesc f); /* NewProduction - creates a new production and returns the data structure. */ static pge_ProductionDesc NewProduction (void); /* NewFactor - */ static pge_FactorDesc NewFactor (void); /* NewTerm - returns a new term. */ static pge_TermDesc NewTerm (void); /* NewExpression - returns a new expression. */ static pge_ExpressionDesc NewExpression (void); /* NewStatement - returns a new statement. */ static pge_StatementDesc NewStatement (void); /* NewSetDesc - creates a new set description and returns the data structure. */ static pge_SetDesc NewSetDesc (void); /* NewCodeDesc - creates a new code descriptor and initializes all fields to zero. */ static pge_CodeDesc NewCodeDesc (void); /* CodeFragmentPrologue - consumes code text up to a "%" after a newline. */ static void CodeFragmentPrologue (void); /* CodeFragmentEpilogue - consumes code text up to a "%" after a newline. */ static void CodeFragmentEpilogue (void); /* CodeFragmentDeclaration - consumes code text up to a "%" after a newline. */ static void CodeFragmentDeclaration (void); /* GetCodeFragment - collects the code fragment up until ^ % */ static void GetCodeFragment (pge_CodeHunk *h); /* WriteCodeHunkList - writes the CodeHunk list in the correct order. */ static void WriteCodeHunkList (pge_CodeHunk l); /* WriteIndent - writes, n, spaces. */ static void WriteIndent (unsigned int n); /* CheckWrite - */ static void CheckWrite (char ch, unsigned int *curpos, unsigned int left, bool *seentext); /* WriteStringIndent - writes a string but it will try and remove upto indent spaces if they exist. */ static void WriteStringIndent (const char *a_, unsigned int _a_high, unsigned int indent, unsigned int *curpos, unsigned int left, bool *seentext); /* WriteCodeHunkListIndent - writes the CodeHunk list in the correct order but it removes up to indent spaces if they exist. */ static void WriteCodeHunkListIndent (pge_CodeHunk l, unsigned int indent, unsigned int *curpos, unsigned int left, bool *seentext); /* Add - adds a character to a code hunk and creates another code hunk if necessary. */ static pge_CodeHunk Add (pge_CodeHunk *p, char ch, unsigned int *i); /* ConsHunk - combine two possible code hunks. */ static void ConsHunk (pge_CodeHunk *p, pge_CodeHunk q); /* GetName - returns the next symbol which is checked for a legal name. */ static NameKey_Name GetName (void); /* SyntaxError - after a syntax error we skip all tokens up until we reach a stop symbol. */ static void SyntaxError (pge_SetOfStop stop); /* SyntaxCheck - */ static void SyntaxCheck (pge_SetOfStop stop); /* Expect - */ static void Expect (bnflex_TokenType t, pge_SetOfStop stop); /* Ident - error checking varient of Ident */ static void Ident (pge_SetOfStop stop); /* Modula2Code - error checking varient of Modula2Code */ static void Modula2Code (pge_SetOfStop stop); /* StartModName := % ModuleName := GetName() ; ignore begintok CodeFragmentPrologue % =: */ static void StartModName (pge_SetOfStop stop); /* EndModName := */ static void EndModName (pge_SetOfStop stop); /* DoDeclaration := % CodeFragmentDeclaration % =: */ static void DoDeclaration (pge_SetOfStop stop); /* CollectLiteral := % LastLiteral := GetCurrentToken() ; AdvanceToken ; % first symbols:literaltok cannot reachend */ static void CollectLiteral (pge_SetOfStop stopset); /* CollectTok := % CurrentSetDesc := NewSetDesc() ; WITH CurrentSetDesc^ DO type := tokel ; string := GetCurrentToken() ; END ; IF NOT ContainsSymKey(Values, GetCurrentToken()) THEN AddEntry(Values, GetCurrentToken(), LargestValue) ; AddEntry(ReverseValues, Name(LargestValue), GetCurrentToken()) ; AddEntry(Aliases, GetCurrentToken(), GetCurrentToken()) ; AddEntry(ReverseAliases, GetCurrentToken(), GetCurrentToken()) ; INC(LargestValue) END ; AdvanceToken() ; % first symbols:identtok cannot reachend */ static void CollectTok (pge_SetOfStop stopset); /* DefineToken := % AddEntry(Aliases, LastLiteral, GetCurrentToken()) ; AddEntry(ReverseAliases, GetCurrentToken(), LastLiteral) ; AddEntry(Values, GetCurrentToken(), LargestValue) ; AddEntry(ReverseValues, Name(LargestValue), GetCurrentToken()) ; INC(LargestValue) ; AdvanceToken ; % first symbols:identtok cannot reachend */ static void DefineToken (pge_SetOfStop stopset); /* Rules := '%' 'rules' { Defs } ExtBNF first symbols:codetok cannot reachend */ static void Rules (pge_SetOfStop stopset); /* Special := Ident % VAR p: ProductionDesc ; % % p := NewProduction() ; p^.statement := NewStatement() ; p^.statement^.followinfo^.calcfollow := TRUE ; p^.statement^.followinfo^.epsilon := false ; p^.statement^.followinfo^.reachend := false ; p^.statement^.ident := CurrentIdent ; p^.statement^.expr := NIL ; p^.firstsolved := TRUE ; p^.followinfo^.calcfollow := TRUE ; p^.followinfo^.epsilon := false ; p^.followinfo^.reachend := false % First Follow [ 'epsilon' % p^.statement^.followinfo^.epsilon := true ; these are not used - but they are displayed when debugging p^.statement^.followinfo^.reachend := true ; p^.followinfo^.epsilon := true ; p^.followinfo^.reachend := true % ] [ Literal % p^.description := LastLiteral % ] first symbols:identtok cannot reachend */ static void Special (pge_SetOfStop stopset); /* Factor := '%' Modula2Code '%' | Ident % WITH CurrentFactor^ DO type := id ; ident := CurrentIdent END ; % | Literal % WITH CurrentFactor^ DO type := lit ; string := LastLiteral ; IF GetSymKey(Aliases, LastLiteral)=NulName THEN WarnError1('no token defined for literal %s', LastLiteral) END END ; % | '{' % WITH CurrentFactor^ DO type := mult ; expr := NewExpression() ; CurrentExpression := expr ; END ; % Expression '}' | '[' % WITH CurrentFactor^ DO type := opt ; expr := NewExpression() ; CurrentExpression := expr ; END ; % Expression ']' | '(' % WITH CurrentFactor^ DO type := sub ; expr := NewExpression() ; CurrentExpression := expr ; END ; % Expression ')' first symbols:dquotetok, squotetok, lparatok, lsparatok, lcparatok, identtok, codetok cannot reachend */ static void Factor (pge_SetOfStop stopset); /* Statement := % VAR i: IdentDesc ; % Ident % VAR p: ProductionDesc ; % % p := FindDefinition(CurrentIdent^.name) ; IF p=NIL THEN p := NewProduction() ELSE IF NOT ((p^.statement=NIL) OR (p^.statement^.expr=NIL)) THEN WarnError1('already declared rule %s', CurrentIdent^.name) END END ; i := CurrentIdent ; % ':=' % VAR e: ExpressionDesc ; % % e := NewExpression() ; CurrentExpression := e ; % % VAR s: StatementDesc ; % % s := NewStatement() ; WITH s^ DO ident := i ; expr := e END ; % Expression % p^.statement := s ; % '=:' first symbols:identtok cannot reachend */ static void Statement (pge_SetOfStop stopset); /* Defs := 'special' Special | 'token' Token | 'error' ErrorProcedures | 'tokenfunc' TokenProcedure | 'symfunc' SymProcedure first symbols:symfunctok, tfunctok, errortok, tokentok, specialtok cannot reachend */ static void Defs (pge_SetOfStop stopset); /* ExtBNF := 'BNF' { Production } 'FNB' first symbols:BNFtok cannot reachend */ static void ExtBNF (pge_SetOfStop stopset); /* Main := Header Decls Footer Rules first symbols:codetok cannot reachend */ static void Main (pge_SetOfStop stopset); /* Header := '%' 'module' StartModName first symbols:codetok cannot reachend */ static void Header (pge_SetOfStop stopset); /* Decls := '%' 'declaration' DoDeclaration first symbols:codetok cannot reachend */ static void Decls (pge_SetOfStop stopset); /* Footer := '%' 'module' EndModName first symbols:codetok cannot reachend */ static void Footer (pge_SetOfStop stopset); /* First := 'first' '{' { LitOrTokenOrIdent % WITH CurrentSetDesc^ DO next := TailProduction^.first ; END ; TailProduction^.first := CurrentSetDesc % } '}' first symbols:firsttok cannot reachend */ static void First (pge_SetOfStop stopset); /* Follow := 'follow' '{' { LitOrTokenOrIdent % WITH CurrentSetDesc^ DO next := TailProduction^.followinfo^.follow ; END ; TailProduction^.followinfo^.follow := CurrentSetDesc % } '}' first symbols:followtok cannot reachend */ static void Follow (pge_SetOfStop stopset); /* LitOrTokenOrIdent := Literal % CurrentSetDesc := NewSetDesc() ; WITH CurrentSetDesc^ DO type := litel ; string := LastLiteral ; END ; % | '<' CollectTok '>' | Ident % CurrentSetDesc := NewSetDesc() ; WITH CurrentSetDesc^ DO type := idel ; ident := CurrentIdent ; END ; % first symbols:dquotetok, squotetok, identtok, lesstok cannot reachend */ static void LitOrTokenOrIdent (pge_SetOfStop stopset); /* Literal := '"' CollectLiteral '"' | "'" CollectLiteral "'" first symbols:squotetok, dquotetok cannot reachend */ static void Literal (pge_SetOfStop stopset); /* Token := Literal DefineToken first symbols:dquotetok, squotetok cannot reachend */ static void Token (pge_SetOfStop stopset); /* ErrorProcedures := Literal % ErrorProcArray := LastLiteral % Literal % ErrorProcString := LastLiteral % first symbols:dquotetok, squotetok cannot reachend */ static void ErrorProcedures (pge_SetOfStop stopset); /* TokenProcedure := Literal % TokenTypeProc := LastLiteral % first symbols:dquotetok, squotetok cannot reachend */ static void TokenProcedure (pge_SetOfStop stopset); /* SymProcedure := Literal % SymIsProc := LastLiteral % first symbols:dquotetok, squotetok cannot reachend */ static void SymProcedure (pge_SetOfStop stopset); /* Production := Statement first symbols:identtok cannot reachend */ static void Production (pge_SetOfStop stopset); /* Expression := % VAR t1, t2: TermDesc ; e : ExpressionDesc ; % % e := CurrentExpression ; t1 := NewTerm() ; CurrentTerm := t1 ; % Term % e^.term := t1 ; % { '|' % t2 := NewTerm() ; CurrentTerm := t2 % Term % t1^.next := t2 ; t1 := t2 % } first symbols:dquotetok, squotetok, lparatok, lsparatok, lcparatok, identtok, codetok cannot reachend */ static void Expression (pge_SetOfStop stopset); /* Term := % VAR t1: TermDesc ; f1, f2: FactorDesc ; % % CurrentFactor := NewFactor() ; f1 := CurrentFactor ; t1 := CurrentTerm ; % Factor % t1^.factor := f1 ; f2 := NewFactor() ; CurrentFactor := f2 % { Factor % f1^.next := f2 ; f1 := f2 ; f2 := NewFactor() ; CurrentFactor := f2 ; % } first symbols:squotetok, dquotetok, codetok, identtok, lcparatok, lsparatok, lparatok cannot reachend */ static void Term (pge_SetOfStop stopset); /* GetDefinitionName - returns the name of the rule inside, p. */ static NameKey_Name GetDefinitionName (pge_ProductionDesc p); /* FindDefinition - searches and returns the rule which defines, n. */ static pge_ProductionDesc FindDefinition (NameKey_Name n); /* BackPatchIdent - found an ident, i, we must look for the corresponding rule and set the definition accordingly. */ static void BackPatchIdent (pge_IdentDesc i); /* BackPatchFactor - runs through the factor looking for an ident */ static void BackPatchFactor (pge_FactorDesc f); /* BackPatchTerm - runs through all terms to find idents. */ static void BackPatchTerm (pge_TermDesc t); /* BackPatchExpression - runs through the term to find any idents. */ static void BackPatchExpression (pge_ExpressionDesc e); /* BackPatchSet - */ static void BackPatchSet (pge_SetDesc s); /* BackPatchIdentToDefinitions - search through all the rules and add a link from any ident to the definition. */ static void BackPatchIdentToDefinitions (pge_ProductionDesc d); /* CalculateFirstAndFollow - */ static void CalculateFirstAndFollow (pge_ProductionDesc p); /* ForeachRuleDo - */ static void ForeachRuleDo (pge_DoProcedure p); /* WhileNotCompleteDo - */ static void WhileNotCompleteDo (pge_DoProcedure p); /* NewLine - generate a newline and indent. */ static void NewLine (unsigned int Left); /* CheckNewLine - */ static void CheckNewLine (unsigned int Left); /* IndentString - writes out a string with a preceeding indent. */ static void IndentString (const char *a_, unsigned int _a_high); /* KeyWord - writes out a keywork with optional formatting directives. */ static void KeyWord (NameKey_Name n); /* PrettyPara - */ static void PrettyPara (const char *c1_, unsigned int _c1_high, const char *c2_, unsigned int _c2_high, pge_ExpressionDesc e, unsigned int Left); /* WriteKeyTexinfo - */ static void WriteKeyTexinfo (NameKey_Name s); /* PrettyCommentFactor - */ static void PrettyCommentFactor (pge_FactorDesc f, unsigned int Left); /* PeepTerm - returns the length of characters in term. */ static unsigned int PeepTerm (pge_TermDesc t); /* PeepExpression - returns the length of the expression. */ static unsigned int PeepExpression (pge_ExpressionDesc e); /* PeepFactor - returns the length of character in the factor */ static unsigned int PeepFactor (pge_FactorDesc f); /* PrettyCommentTerm - */ static void PrettyCommentTerm (pge_TermDesc t, unsigned int Left); /* PrettyCommentExpression - */ static void PrettyCommentExpression (pge_ExpressionDesc e, unsigned int Left); /* PrettyCommentStatement - */ static void PrettyCommentStatement (pge_StatementDesc s, unsigned int Left); /* PrettyCommentProduction - generates the comment for rule, p. */ static void PrettyCommentProduction (pge_ProductionDesc p); /* PrettyPrintProduction - pretty prints the ebnf rule, p. */ static void PrettyPrintProduction (pge_ProductionDesc p); /* EmitFileLineTag - emits a line and file tag using the C preprocessor syntax. */ static void EmitFileLineTag (unsigned int line); /* EmitRule - generates a comment and code for rule, p. */ static void EmitRule (pge_ProductionDesc p); /* CodeCondition - */ static void CodeCondition (pge_m2condition m); /* CodeThenDo - codes a "THEN" or "DO" depending upon, m. */ static void CodeThenDo (pge_m2condition m); /* CodeElseEnd - builds an ELSE END statement using string, end. */ static void CodeElseEnd (const char *end_, unsigned int _end_high, bool consumed, pge_FactorDesc f, bool inopt); /* CodeEnd - codes a "END" depending upon, m. */ static void CodeEnd (pge_m2condition m, pge_TermDesc t, bool consumed, pge_FactorDesc f, bool inopt); /* EmitNonVarCode - writes out, code, providing it is not a variable declaration. */ static void EmitNonVarCode (pge_CodeDesc code, unsigned int curpos, unsigned int left); /* ChainOn - */ static pge_FactorDesc ChainOn (pge_FactorDesc codeStack, pge_FactorDesc f); /* FlushCode - */ static void FlushCode (pge_FactorDesc *codeStack); /* CodeFactor - */ static void CodeFactor (pge_FactorDesc f, pge_TermDesc t, pge_m2condition l, pge_m2condition n, bool inopt, bool inwhile, bool consumed, pge_FactorDesc codeStack); /* CodeTerm - */ static void CodeTerm (pge_TermDesc t, pge_m2condition m, bool inopt, bool inwhile, bool consumed, pge_FactorDesc codeStack); /* CodeExpression - */ static void CodeExpression (pge_ExpressionDesc e, pge_m2condition m, bool inopt, bool inwhile, bool consumed, pge_FactorDesc codeStack); /* CodeStatement - */ static void CodeStatement (pge_StatementDesc s, pge_m2condition m); /* CodeProduction - only encode grammer rules which are not special. */ static void CodeProduction (pge_ProductionDesc p); /* RecoverCondition - */ static void RecoverCondition (pge_m2condition m); /* ConditionIndent - returns the number of spaces indentation created via, m. */ static unsigned int ConditionIndent (pge_m2condition m); /* WriteGetTokenType - writes out the method of determining the token type. */ static void WriteGetTokenType (void); /* NumberOfElements - returns the number of elements in set, to, which lie between low..high */ static unsigned int NumberOfElements (pge_SetDesc to, unsigned int low, unsigned int high); /* WriteElement - writes the literal name for element, e. */ static void WriteElement (unsigned int e); /* EmitIsInSet - writes out the equivalent of GetTokenType() IN { toset } */ static void EmitIsInSet (pge_SetDesc to, NameKey_Name low, NameKey_Name high); /* EmitIsInSubSet - writes out a test to see whether GetTokenype() is in { subset } */ static void EmitIsInSubSet (pge_SetDesc to, unsigned int low, unsigned int high); /* EmitIsInFirst - */ static void EmitIsInFirst (pge_SetDesc to, pge_m2condition m); static void FlushRecoverCode (pge_FactorDesc *codeStack); /* RecoverFactor - */ static void RecoverFactor (pge_FactorDesc f, pge_m2condition m, pge_FactorDesc codeStack); /* OptExpSeen - returns TRUE if we can see an optional expression in the factor. This is not the same as epsilon. Example { '+' } matches epsilon as well as { '+' | '-' } but OptExpSeen returns TRUE in the second case and FALSE in the first. */ static bool OptExpSeen (pge_FactorDesc f); /* RecoverTerm - */ static void RecoverTerm (pge_TermDesc t, pge_m2condition new_, pge_m2condition old); /* RecoverExpression - */ static void RecoverExpression (pge_ExpressionDesc e, pge_m2condition new_, pge_m2condition old); /* RecoverStatement - */ static void RecoverStatement (pge_StatementDesc s, pge_m2condition m); /* EmitFirstFactor - generate a list of all first tokens between the range: low..high. */ static void EmitFirstFactor (pge_FactorDesc f, unsigned int low, unsigned int high); /* EmitUsed - */ static void EmitUsed (unsigned int wordno); /* EmitStopParameters - generate the stop set. */ static void EmitStopParameters (bool FormalParameters); /* IsBetween - returns TRUE if the value of the token, string, is in the range: low..high */ static bool IsBetween (NameKey_Name string, unsigned int low, unsigned int high); /* IsEmptySet - returns TRUE if no elements exist in set, to, with values, low..high. */ static bool IsEmptySet (pge_SetDesc to, unsigned int low, unsigned int high); /* EmitSet - emits the tokens in the set, to, which have values low..high */ static void EmitSet (pge_SetDesc to, unsigned int low, unsigned int high); /* EmitSetName - emits the tokens in the set, to, which have values low..high, using their names. */ static void EmitSetName (pge_SetDesc to, unsigned int low, unsigned int high); /* EmitStopParametersAndSet - generates the stop parameters together with a set inclusion of all the symbols in set, to. */ static void EmitStopParametersAndSet (pge_SetDesc to); /* EmitSetAsParameters - generates the first symbols as parameters to a set function. */ static void EmitSetAsParameters (pge_SetDesc to); /* EmitStopParametersAndFollow - generates the stop parameters together with a set inclusion of all the follow symbols for subsequent sentances. */ static void EmitStopParametersAndFollow (pge_FactorDesc f, pge_m2condition m); /* EmitFirstAsParameters - */ static void EmitFirstAsParameters (pge_FactorDesc f); /* RecoverProduction - only encode grammer rules which are not special. Generate error recovery code. */ static void RecoverProduction (pge_ProductionDesc p); /* IsWhite - returns TRUE if, ch, is a space or a tab. */ static bool IsWhite (char ch); /* FindStr - returns TRUE if, str, was seen inside the code hunk */ static bool FindStr (pge_CodeHunk *code, unsigned int *i, const char *str_, unsigned int _str_high); /* WriteUpto - */ static void WriteUpto (pge_CodeHunk code, pge_CodeHunk upto, unsigned int limit); /* CheckForVar - checks for any local variables which need to be emitted during this production. */ static void CheckForVar (pge_CodeHunk code); /* VarFactor - */ static void VarFactor (pge_FactorDesc f); /* VarTerm - */ static void VarTerm (pge_TermDesc t); /* VarExpression - */ static void VarExpression (pge_ExpressionDesc e); /* VarStatement - */ static void VarStatement (pge_StatementDesc s); /* VarProduction - writes out all variable declarations. */ static void VarProduction (pge_ProductionDesc p); /* In - returns TRUE if token, s, is already in the set, to. */ static bool In (pge_SetDesc to, NameKey_Name s); /* IntersectionIsNil - given two set lists, s1, s2, return TRUE if the s1 * s2 = {} */ static bool IntersectionIsNil (pge_SetDesc s1, pge_SetDesc s2); /* AddSet - adds a first symbol to a production. */ static void AddSet (pge_SetDesc *to, NameKey_Name s); /* OrSet - */ static void OrSet (pge_SetDesc *to, pge_SetDesc from); /* CalcFirstFactor - */ static void CalcFirstFactor (pge_FactorDesc f, pge_ProductionDesc from, pge_SetDesc *to); /* CalcFirstTerm - */ static void CalcFirstTerm (pge_TermDesc t, pge_ProductionDesc from, pge_SetDesc *to); /* CalcFirstExpression - */ static void CalcFirstExpression (pge_ExpressionDesc e, pge_ProductionDesc from, pge_SetDesc *to); /* CalcFirstStatement - */ static void CalcFirstStatement (pge_StatementDesc s, pge_ProductionDesc from, pge_SetDesc *to); /* CalcFirstProduction - calculates all of the first symbols for the grammer */ static void CalcFirstProduction (pge_ProductionDesc p, pge_ProductionDesc from, pge_SetDesc *to); static void WorkOutFollowFactor (pge_FactorDesc f, pge_SetDesc *followset, pge_SetDesc after); /* WorkOutFollowTerm - */ static void WorkOutFollowTerm (pge_TermDesc t, pge_SetDesc *followset, pge_SetDesc after); /* WorkOutFollowExpression - */ static void WorkOutFollowExpression (pge_ExpressionDesc e, pge_SetDesc *followset, pge_SetDesc after); /* CollectFollow - collects the follow set from, f, into, to. */ static void CollectFollow (pge_SetDesc *to, pge_FollowDesc f); /* CalcFollowFactor - */ static void CalcFollowFactor (pge_FactorDesc f, pge_SetDesc after); /* CalcFollowTerm - */ static void CalcFollowTerm (pge_TermDesc t, pge_SetDesc after); /* CalcFollowExpression - */ static void CalcFollowExpression (pge_ExpressionDesc e, pge_SetDesc after); /* CalcFollowStatement - given a bnf statement generate the follow set. */ static void CalcFollowStatement (pge_StatementDesc s); /* CalcFollowProduction - */ static void CalcFollowProduction (pge_ProductionDesc p); /* CalcEpsilonFactor - */ static void CalcEpsilonFactor (pge_FactorDesc f); /* CalcEpsilonTerm - */ static void CalcEpsilonTerm (pge_TermDesc t); /* CalcEpsilonExpression - */ static void CalcEpsilonExpression (pge_ExpressionDesc e); /* CalcEpsilonStatement - given a bnf statement generate the follow set. */ static void CalcEpsilonStatement (pge_StatementDesc s); /* CalcEpsilonProduction - */ static void CalcEpsilonProduction (pge_ProductionDesc p); /* CalcReachEndFactor - */ static pge_TraverseResult CalcReachEndFactor (pge_FactorDesc f); /* CalcReachEndTerm - */ static pge_TraverseResult CalcReachEndTerm (pge_TermDesc t); /* CalcReachEndExpression - */ static void CalcReachEndExpression (pge_ExpressionDesc e); /* CalcReachEndStatement - */ static void CalcReachEndStatement (pge_StatementDesc s); /* CalcReachEndStatement - */ static void stop (void); /* CalcReachEndProduction - */ static void CalcReachEndProduction (pge_ProductionDesc p); /* EmptyFactor - */ static bool EmptyFactor (pge_FactorDesc f); /* EmptyTerm - returns TRUE if the term maybe empty. */ static bool EmptyTerm (pge_TermDesc t); /* EmptyExpression - */ static bool EmptyExpression (pge_ExpressionDesc e); /* EmptyStatement - returns TRUE if statement, s, is empty. */ static bool EmptyStatement (pge_StatementDesc s); /* EmptyProduction - returns if production, p, maybe empty. */ static bool EmptyProduction (pge_ProductionDesc p); /* EmitFDLNotice - */ static void EmitFDLNotice (void); /* EmitRules - generates the BNF rules. */ static void EmitRules (void); /* DescribeElement - */ static void DescribeElement (unsigned int name); /* EmitInTestStop - construct a test for stop element, name. */ static void EmitInTestStop (NameKey_Name name); /* DescribeStopElement - */ static void DescribeStopElement (unsigned int name); /* EmitDescribeStop - */ static void EmitDescribeStop (void); /* EmitDescribeError - */ static void EmitDescribeError (void); /* EmitSetTypes - write out the set types used during error recovery */ static void EmitSetTypes (void); /* EmitSupport - generates the support routines. */ static void EmitSupport (void); /* DisposeSetDesc - dispose of the set list, s. */ static void DisposeSetDesc (pge_SetDesc *s); /* OptionalFactor - */ static bool OptionalFactor (pge_FactorDesc f); /* OptionalTerm - returns TRUE if the term maybe empty. */ static bool OptionalTerm (pge_TermDesc t); /* OptionalExpression - */ static bool OptionalExpression (pge_ExpressionDesc e); /* OptionalStatement - returns FALSE if statement, s, does not have a optional ambiguity. */ static bool OptionalStatement (pge_StatementDesc s); /* OptionalProduction - */ static bool OptionalProduction (pge_ProductionDesc p); /* CheckFirstFollow - */ static bool CheckFirstFollow (pge_FactorDesc f, pge_FactorDesc after); /* ConstrainedEmptyFactor - */ static bool ConstrainedEmptyFactor (pge_FactorDesc f); /* ConstrainedEmptyTerm - returns TRUE if the term maybe empty. */ static bool ConstrainedEmptyTerm (pge_TermDesc t); /* ConstrainedEmptyExpression - */ static bool ConstrainedEmptyExpression (pge_ExpressionDesc e); /* ConstrainedEmptyStatement - returns FALSE if statement, s, does not have a optional ambiguity. */ static bool ConstrainedEmptyStatement (pge_StatementDesc s); /* ConstrainedEmptyProduction - returns TRUE if a problem exists with, p. */ static bool ConstrainedEmptyProduction (pge_ProductionDesc p); /* TestForLALR1 - */ static void TestForLALR1 (pge_ProductionDesc p); /* DoEpsilon - runs the epsilon interrelated rules */ static void DoEpsilon (pge_ProductionDesc p); /* CheckComplete - checks that production, p, is complete. */ static void CheckComplete (pge_ProductionDesc p); /* PostProcessRules - backpatch the ident to rule definitions and emit comments and code. */ static void PostProcessRules (void); /* DisplayHelp - display a summary help and then exit (0). */ static void DisplayHelp (void); /* ParseArgs - */ static void ParseArgs (void); /* Init - initialize the modules data structures */ static void Init (void); /* DescribeStop - issues a message explaining what tokens were expected */ static DynamicStrings_String DescribeStop (pge_SetOfStop stopset); /* DescribeError - issues a message explaining what tokens were expected */ static void DescribeError (void); /* AddEntry - adds an entry into, t, containing [def:value]. */ static void AddEntry (SymbolKey_SymbolTree *t, NameKey_Name def, NameKey_Name value); /* Format1 - converts string, src, into, dest, together with encapsulated entity, n. It only formats the first %s or %d with n. */ static void Format1 (const char *src_, unsigned int _src_high, unsigned int n, char *dest, unsigned int _dest_high); /* WarnError1 - */ static void WarnError1 (const char *a_, unsigned int _a_high, unsigned int n); /* PrettyFollow - */ static void PrettyFollow (const char *start_, unsigned int _start_high, const char *end_, unsigned int _end_high, pge_FollowDesc f); /* NewFollow - creates a new follow descriptor and returns the data structure. */ static pge_FollowDesc NewFollow (void); /* AssignEpsilon - assigns the epsilon value and sets the epsilon to value, providing condition is TRUE. */ static void AssignEpsilon (bool condition, pge_FollowDesc f, pge_TraverseResult value); /* GetEpsilon - returns the value of epsilon */ static pge_TraverseResult GetEpsilon (pge_FollowDesc f); /* AssignReachEnd - assigns the reachend value providing that, condition, is TRUE. */ static void AssignReachEnd (bool condition, pge_FollowDesc f, pge_TraverseResult value); /* GetReachEnd - returns the value of reachend */ static pge_TraverseResult GetReachEnd (pge_FollowDesc f); /* AssignFollow - assigns the follow set and sets the calcfollow to TRUE. */ static void AssignFollow (pge_FollowDesc f, pge_SetDesc s); /* GetFollow - returns the follow set. */ static pge_SetDesc GetFollow (pge_FollowDesc f); /* NewProduction - creates a new production and returns the data structure. */ static pge_ProductionDesc NewProduction (void); /* NewFactor - */ static pge_FactorDesc NewFactor (void); /* NewTerm - returns a new term. */ static pge_TermDesc NewTerm (void); /* NewExpression - returns a new expression. */ static pge_ExpressionDesc NewExpression (void); /* NewStatement - returns a new statement. */ static pge_StatementDesc NewStatement (void); /* NewSetDesc - creates a new set description and returns the data structure. */ static pge_SetDesc NewSetDesc (void); /* NewCodeDesc - creates a new code descriptor and initializes all fields to zero. */ static pge_CodeDesc NewCodeDesc (void); /* CodeFragmentPrologue - consumes code text up to a "%" after a newline. */ static void CodeFragmentPrologue (void); /* CodeFragmentEpilogue - consumes code text up to a "%" after a newline. */ static void CodeFragmentEpilogue (void); /* CodeFragmentDeclaration - consumes code text up to a "%" after a newline. */ static void CodeFragmentDeclaration (void); /* GetCodeFragment - collects the code fragment up until ^ % */ static void GetCodeFragment (pge_CodeHunk *h); /* WriteCodeHunkList - writes the CodeHunk list in the correct order. */ static void WriteCodeHunkList (pge_CodeHunk l); /* WriteIndent - writes, n, spaces. */ static void WriteIndent (unsigned int n); /* CheckWrite - */ static void CheckWrite (char ch, unsigned int *curpos, unsigned int left, bool *seentext); /* WriteStringIndent - writes a string but it will try and remove upto indent spaces if they exist. */ static void WriteStringIndent (const char *a_, unsigned int _a_high, unsigned int indent, unsigned int *curpos, unsigned int left, bool *seentext); /* WriteCodeHunkListIndent - writes the CodeHunk list in the correct order but it removes up to indent spaces if they exist. */ static void WriteCodeHunkListIndent (pge_CodeHunk l, unsigned int indent, unsigned int *curpos, unsigned int left, bool *seentext); /* Add - adds a character to a code hunk and creates another code hunk if necessary. */ static pge_CodeHunk Add (pge_CodeHunk *p, char ch, unsigned int *i); /* ConsHunk - combine two possible code hunks. */ static void ConsHunk (pge_CodeHunk *p, pge_CodeHunk q); /* GetName - returns the next symbol which is checked for a legal name. */ static NameKey_Name GetName (void); /* SyntaxError - after a syntax error we skip all tokens up until we reach a stop symbol. */ static void SyntaxError (pge_SetOfStop stop); /* SyntaxCheck - */ static void SyntaxCheck (pge_SetOfStop stop); /* Expect - */ static void Expect (bnflex_TokenType t, pge_SetOfStop stop); /* Ident - error checking varient of Ident */ static void Ident (pge_SetOfStop stop); /* Modula2Code - error checking varient of Modula2Code */ static void Modula2Code (pge_SetOfStop stop); /* StartModName := % ModuleName := GetName() ; ignore begintok CodeFragmentPrologue % =: */ static void StartModName (pge_SetOfStop stop); /* EndModName := */ static void EndModName (pge_SetOfStop stop); /* DoDeclaration := % CodeFragmentDeclaration % =: */ static void DoDeclaration (pge_SetOfStop stop); /* CollectLiteral := % LastLiteral := GetCurrentToken() ; AdvanceToken ; % first symbols:literaltok cannot reachend */ static void CollectLiteral (pge_SetOfStop stopset); /* CollectTok := % CurrentSetDesc := NewSetDesc() ; WITH CurrentSetDesc^ DO type := tokel ; string := GetCurrentToken() ; END ; IF NOT ContainsSymKey(Values, GetCurrentToken()) THEN AddEntry(Values, GetCurrentToken(), LargestValue) ; AddEntry(ReverseValues, Name(LargestValue), GetCurrentToken()) ; AddEntry(Aliases, GetCurrentToken(), GetCurrentToken()) ; AddEntry(ReverseAliases, GetCurrentToken(), GetCurrentToken()) ; INC(LargestValue) END ; AdvanceToken() ; % first symbols:identtok cannot reachend */ static void CollectTok (pge_SetOfStop stopset); /* DefineToken := % AddEntry(Aliases, LastLiteral, GetCurrentToken()) ; AddEntry(ReverseAliases, GetCurrentToken(), LastLiteral) ; AddEntry(Values, GetCurrentToken(), LargestValue) ; AddEntry(ReverseValues, Name(LargestValue), GetCurrentToken()) ; INC(LargestValue) ; AdvanceToken ; % first symbols:identtok cannot reachend */ static void DefineToken (pge_SetOfStop stopset); /* Rules := '%' 'rules' { Defs } ExtBNF first symbols:codetok cannot reachend */ static void Rules (pge_SetOfStop stopset); /* Special := Ident % VAR p: ProductionDesc ; % % p := NewProduction() ; p^.statement := NewStatement() ; p^.statement^.followinfo^.calcfollow := TRUE ; p^.statement^.followinfo^.epsilon := false ; p^.statement^.followinfo^.reachend := false ; p^.statement^.ident := CurrentIdent ; p^.statement^.expr := NIL ; p^.firstsolved := TRUE ; p^.followinfo^.calcfollow := TRUE ; p^.followinfo^.epsilon := false ; p^.followinfo^.reachend := false % First Follow [ 'epsilon' % p^.statement^.followinfo^.epsilon := true ; these are not used - but they are displayed when debugging p^.statement^.followinfo^.reachend := true ; p^.followinfo^.epsilon := true ; p^.followinfo^.reachend := true % ] [ Literal % p^.description := LastLiteral % ] first symbols:identtok cannot reachend */ static void Special (pge_SetOfStop stopset); /* Factor := '%' Modula2Code '%' | Ident % WITH CurrentFactor^ DO type := id ; ident := CurrentIdent END ; % | Literal % WITH CurrentFactor^ DO type := lit ; string := LastLiteral ; IF GetSymKey(Aliases, LastLiteral)=NulName THEN WarnError1('no token defined for literal %s', LastLiteral) END END ; % | '{' % WITH CurrentFactor^ DO type := mult ; expr := NewExpression() ; CurrentExpression := expr ; END ; % Expression '}' | '[' % WITH CurrentFactor^ DO type := opt ; expr := NewExpression() ; CurrentExpression := expr ; END ; % Expression ']' | '(' % WITH CurrentFactor^ DO type := sub ; expr := NewExpression() ; CurrentExpression := expr ; END ; % Expression ')' first symbols:dquotetok, squotetok, lparatok, lsparatok, lcparatok, identtok, codetok cannot reachend */ static void Factor (pge_SetOfStop stopset); /* Statement := % VAR i: IdentDesc ; % Ident % VAR p: ProductionDesc ; % % p := FindDefinition(CurrentIdent^.name) ; IF p=NIL THEN p := NewProduction() ELSE IF NOT ((p^.statement=NIL) OR (p^.statement^.expr=NIL)) THEN WarnError1('already declared rule %s', CurrentIdent^.name) END END ; i := CurrentIdent ; % ':=' % VAR e: ExpressionDesc ; % % e := NewExpression() ; CurrentExpression := e ; % % VAR s: StatementDesc ; % % s := NewStatement() ; WITH s^ DO ident := i ; expr := e END ; % Expression % p^.statement := s ; % '=:' first symbols:identtok cannot reachend */ static void Statement (pge_SetOfStop stopset); /* Defs := 'special' Special | 'token' Token | 'error' ErrorProcedures | 'tokenfunc' TokenProcedure | 'symfunc' SymProcedure first symbols:symfunctok, tfunctok, errortok, tokentok, specialtok cannot reachend */ static void Defs (pge_SetOfStop stopset); /* ExtBNF := 'BNF' { Production } 'FNB' first symbols:BNFtok cannot reachend */ static void ExtBNF (pge_SetOfStop stopset); /* Main := Header Decls Footer Rules first symbols:codetok cannot reachend */ static void Main (pge_SetOfStop stopset); /* Header := '%' 'module' StartModName first symbols:codetok cannot reachend */ static void Header (pge_SetOfStop stopset); /* Decls := '%' 'declaration' DoDeclaration first symbols:codetok cannot reachend */ static void Decls (pge_SetOfStop stopset); /* Footer := '%' 'module' EndModName first symbols:codetok cannot reachend */ static void Footer (pge_SetOfStop stopset); /* First := 'first' '{' { LitOrTokenOrIdent % WITH CurrentSetDesc^ DO next := TailProduction^.first ; END ; TailProduction^.first := CurrentSetDesc % } '}' first symbols:firsttok cannot reachend */ static void First (pge_SetOfStop stopset); /* Follow := 'follow' '{' { LitOrTokenOrIdent % WITH CurrentSetDesc^ DO next := TailProduction^.followinfo^.follow ; END ; TailProduction^.followinfo^.follow := CurrentSetDesc % } '}' first symbols:followtok cannot reachend */ static void Follow (pge_SetOfStop stopset); /* LitOrTokenOrIdent := Literal % CurrentSetDesc := NewSetDesc() ; WITH CurrentSetDesc^ DO type := litel ; string := LastLiteral ; END ; % | '<' CollectTok '>' | Ident % CurrentSetDesc := NewSetDesc() ; WITH CurrentSetDesc^ DO type := idel ; ident := CurrentIdent ; END ; % first symbols:dquotetok, squotetok, identtok, lesstok cannot reachend */ static void LitOrTokenOrIdent (pge_SetOfStop stopset); /* Literal := '"' CollectLiteral '"' | "'" CollectLiteral "'" first symbols:squotetok, dquotetok cannot reachend */ static void Literal (pge_SetOfStop stopset); /* Token := Literal DefineToken first symbols:dquotetok, squotetok cannot reachend */ static void Token (pge_SetOfStop stopset); /* ErrorProcedures := Literal % ErrorProcArray := LastLiteral % Literal % ErrorProcString := LastLiteral % first symbols:dquotetok, squotetok cannot reachend */ static void ErrorProcedures (pge_SetOfStop stopset); /* TokenProcedure := Literal % TokenTypeProc := LastLiteral % first symbols:dquotetok, squotetok cannot reachend */ static void TokenProcedure (pge_SetOfStop stopset); /* SymProcedure := Literal % SymIsProc := LastLiteral % first symbols:dquotetok, squotetok cannot reachend */ static void SymProcedure (pge_SetOfStop stopset); /* Production := Statement first symbols:identtok cannot reachend */ static void Production (pge_SetOfStop stopset); /* Expression := % VAR t1, t2: TermDesc ; e : ExpressionDesc ; % % e := CurrentExpression ; t1 := NewTerm() ; CurrentTerm := t1 ; % Term % e^.term := t1 ; % { '|' % t2 := NewTerm() ; CurrentTerm := t2 % Term % t1^.next := t2 ; t1 := t2 % } first symbols:dquotetok, squotetok, lparatok, lsparatok, lcparatok, identtok, codetok cannot reachend */ static void Expression (pge_SetOfStop stopset); /* Term := % VAR t1: TermDesc ; f1, f2: FactorDesc ; % % CurrentFactor := NewFactor() ; f1 := CurrentFactor ; t1 := CurrentTerm ; % Factor % t1^.factor := f1 ; f2 := NewFactor() ; CurrentFactor := f2 % { Factor % f1^.next := f2 ; f1 := f2 ; f2 := NewFactor() ; CurrentFactor := f2 ; % } first symbols:squotetok, dquotetok, codetok, identtok, lcparatok, lsparatok, lparatok cannot reachend */ static void Term (pge_SetOfStop stopset); /* GetDefinitionName - returns the name of the rule inside, p. */ static NameKey_Name GetDefinitionName (pge_ProductionDesc p); /* FindDefinition - searches and returns the rule which defines, n. */ static pge_ProductionDesc FindDefinition (NameKey_Name n); /* BackPatchIdent - found an ident, i, we must look for the corresponding rule and set the definition accordingly. */ static void BackPatchIdent (pge_IdentDesc i); /* BackPatchFactor - runs through the factor looking for an ident */ static void BackPatchFactor (pge_FactorDesc f); /* BackPatchTerm - runs through all terms to find idents. */ static void BackPatchTerm (pge_TermDesc t); /* BackPatchExpression - runs through the term to find any idents. */ static void BackPatchExpression (pge_ExpressionDesc e); /* BackPatchSet - */ static void BackPatchSet (pge_SetDesc s); /* BackPatchIdentToDefinitions - search through all the rules and add a link from any ident to the definition. */ static void BackPatchIdentToDefinitions (pge_ProductionDesc d); /* CalculateFirstAndFollow - */ static void CalculateFirstAndFollow (pge_ProductionDesc p); /* ForeachRuleDo - */ static void ForeachRuleDo (pge_DoProcedure p); /* WhileNotCompleteDo - */ static void WhileNotCompleteDo (pge_DoProcedure p); /* NewLine - generate a newline and indent. */ static void NewLine (unsigned int Left); /* CheckNewLine - */ static void CheckNewLine (unsigned int Left); /* IndentString - writes out a string with a preceeding indent. */ static void IndentString (const char *a_, unsigned int _a_high); /* KeyWord - writes out a keywork with optional formatting directives. */ static void KeyWord (NameKey_Name n); /* PrettyPara - */ static void PrettyPara (const char *c1_, unsigned int _c1_high, const char *c2_, unsigned int _c2_high, pge_ExpressionDesc e, unsigned int Left); /* WriteKeyTexinfo - */ static void WriteKeyTexinfo (NameKey_Name s); /* PrettyCommentFactor - */ static void PrettyCommentFactor (pge_FactorDesc f, unsigned int Left); /* PeepTerm - returns the length of characters in term. */ static unsigned int PeepTerm (pge_TermDesc t); /* PeepExpression - returns the length of the expression. */ static unsigned int PeepExpression (pge_ExpressionDesc e); /* PeepFactor - returns the length of character in the factor */ static unsigned int PeepFactor (pge_FactorDesc f); /* PrettyCommentTerm - */ static void PrettyCommentTerm (pge_TermDesc t, unsigned int Left); /* PrettyCommentExpression - */ static void PrettyCommentExpression (pge_ExpressionDesc e, unsigned int Left); /* PrettyCommentStatement - */ static void PrettyCommentStatement (pge_StatementDesc s, unsigned int Left); /* PrettyCommentProduction - generates the comment for rule, p. */ static void PrettyCommentProduction (pge_ProductionDesc p); /* PrettyPrintProduction - pretty prints the ebnf rule, p. */ static void PrettyPrintProduction (pge_ProductionDesc p); /* EmitFileLineTag - emits a line and file tag using the C preprocessor syntax. */ static void EmitFileLineTag (unsigned int line); /* EmitRule - generates a comment and code for rule, p. */ static void EmitRule (pge_ProductionDesc p); /* CodeCondition - */ static void CodeCondition (pge_m2condition m); /* CodeThenDo - codes a "THEN" or "DO" depending upon, m. */ static void CodeThenDo (pge_m2condition m); /* CodeElseEnd - builds an ELSE END statement using string, end. */ static void CodeElseEnd (const char *end_, unsigned int _end_high, bool consumed, pge_FactorDesc f, bool inopt); /* CodeEnd - codes a "END" depending upon, m. */ static void CodeEnd (pge_m2condition m, pge_TermDesc t, bool consumed, pge_FactorDesc f, bool inopt); /* EmitNonVarCode - writes out, code, providing it is not a variable declaration. */ static void EmitNonVarCode (pge_CodeDesc code, unsigned int curpos, unsigned int left); /* ChainOn - */ static pge_FactorDesc ChainOn (pge_FactorDesc codeStack, pge_FactorDesc f); /* FlushCode - */ static void FlushCode (pge_FactorDesc *codeStack); /* CodeFactor - */ static void CodeFactor (pge_FactorDesc f, pge_TermDesc t, pge_m2condition l, pge_m2condition n, bool inopt, bool inwhile, bool consumed, pge_FactorDesc codeStack); /* CodeTerm - */ static void CodeTerm (pge_TermDesc t, pge_m2condition m, bool inopt, bool inwhile, bool consumed, pge_FactorDesc codeStack); /* CodeExpression - */ static void CodeExpression (pge_ExpressionDesc e, pge_m2condition m, bool inopt, bool inwhile, bool consumed, pge_FactorDesc codeStack); /* CodeStatement - */ static void CodeStatement (pge_StatementDesc s, pge_m2condition m); /* CodeProduction - only encode grammer rules which are not special. */ static void CodeProduction (pge_ProductionDesc p); /* RecoverCondition - */ static void RecoverCondition (pge_m2condition m); /* ConditionIndent - returns the number of spaces indentation created via, m. */ static unsigned int ConditionIndent (pge_m2condition m); /* WriteGetTokenType - writes out the method of determining the token type. */ static void WriteGetTokenType (void); /* NumberOfElements - returns the number of elements in set, to, which lie between low..high */ static unsigned int NumberOfElements (pge_SetDesc to, unsigned int low, unsigned int high); /* WriteElement - writes the literal name for element, e. */ static void WriteElement (unsigned int e); /* EmitIsInSet - writes out the equivalent of GetTokenType() IN { toset } */ static void EmitIsInSet (pge_SetDesc to, NameKey_Name low, NameKey_Name high); /* EmitIsInSubSet - writes out a test to see whether GetTokenype() is in { subset } */ static void EmitIsInSubSet (pge_SetDesc to, unsigned int low, unsigned int high); /* EmitIsInFirst - */ static void EmitIsInFirst (pge_SetDesc to, pge_m2condition m); static void FlushRecoverCode (pge_FactorDesc *codeStack); /* RecoverFactor - */ static void RecoverFactor (pge_FactorDesc f, pge_m2condition m, pge_FactorDesc codeStack); /* OptExpSeen - returns TRUE if we can see an optional expression in the factor. This is not the same as epsilon. Example { '+' } matches epsilon as well as { '+' | '-' } but OptExpSeen returns TRUE in the second case and FALSE in the first. */ static bool OptExpSeen (pge_FactorDesc f); /* RecoverTerm - */ static void RecoverTerm (pge_TermDesc t, pge_m2condition new_, pge_m2condition old); /* RecoverExpression - */ static void RecoverExpression (pge_ExpressionDesc e, pge_m2condition new_, pge_m2condition old); /* RecoverStatement - */ static void RecoverStatement (pge_StatementDesc s, pge_m2condition m); /* EmitFirstFactor - generate a list of all first tokens between the range: low..high. */ static void EmitFirstFactor (pge_FactorDesc f, unsigned int low, unsigned int high); /* EmitUsed - */ static void EmitUsed (unsigned int wordno); /* EmitStopParameters - generate the stop set. */ static void EmitStopParameters (bool FormalParameters); /* IsBetween - returns TRUE if the value of the token, string, is in the range: low..high */ static bool IsBetween (NameKey_Name string, unsigned int low, unsigned int high); /* IsEmptySet - returns TRUE if no elements exist in set, to, with values, low..high. */ static bool IsEmptySet (pge_SetDesc to, unsigned int low, unsigned int high); /* EmitSet - emits the tokens in the set, to, which have values low..high */ static void EmitSet (pge_SetDesc to, unsigned int low, unsigned int high); /* EmitSetName - emits the tokens in the set, to, which have values low..high, using their names. */ static void EmitSetName (pge_SetDesc to, unsigned int low, unsigned int high); /* EmitStopParametersAndSet - generates the stop parameters together with a set inclusion of all the symbols in set, to. */ static void EmitStopParametersAndSet (pge_SetDesc to); /* EmitSetAsParameters - generates the first symbols as parameters to a set function. */ static void EmitSetAsParameters (pge_SetDesc to); /* EmitStopParametersAndFollow - generates the stop parameters together with a set inclusion of all the follow symbols for subsequent sentances. */ static void EmitStopParametersAndFollow (pge_FactorDesc f, pge_m2condition m); /* EmitFirstAsParameters - */ static void EmitFirstAsParameters (pge_FactorDesc f); /* RecoverProduction - only encode grammer rules which are not special. Generate error recovery code. */ static void RecoverProduction (pge_ProductionDesc p); /* IsWhite - returns TRUE if, ch, is a space or a tab. */ static bool IsWhite (char ch); /* FindStr - returns TRUE if, str, was seen inside the code hunk */ static bool FindStr (pge_CodeHunk *code, unsigned int *i, const char *str_, unsigned int _str_high); /* WriteUpto - */ static void WriteUpto (pge_CodeHunk code, pge_CodeHunk upto, unsigned int limit); /* CheckForVar - checks for any local variables which need to be emitted during this production. */ static void CheckForVar (pge_CodeHunk code); /* VarFactor - */ static void VarFactor (pge_FactorDesc f); /* VarTerm - */ static void VarTerm (pge_TermDesc t); /* VarExpression - */ static void VarExpression (pge_ExpressionDesc e); /* VarStatement - */ static void VarStatement (pge_StatementDesc s); /* VarProduction - writes out all variable declarations. */ static void VarProduction (pge_ProductionDesc p); /* In - returns TRUE if token, s, is already in the set, to. */ static bool In (pge_SetDesc to, NameKey_Name s); /* IntersectionIsNil - given two set lists, s1, s2, return TRUE if the s1 * s2 = {} */ static bool IntersectionIsNil (pge_SetDesc s1, pge_SetDesc s2); /* AddSet - adds a first symbol to a production. */ static void AddSet (pge_SetDesc *to, NameKey_Name s); /* OrSet - */ static void OrSet (pge_SetDesc *to, pge_SetDesc from); /* CalcFirstFactor - */ static void CalcFirstFactor (pge_FactorDesc f, pge_ProductionDesc from, pge_SetDesc *to); /* CalcFirstTerm - */ static void CalcFirstTerm (pge_TermDesc t, pge_ProductionDesc from, pge_SetDesc *to); /* CalcFirstExpression - */ static void CalcFirstExpression (pge_ExpressionDesc e, pge_ProductionDesc from, pge_SetDesc *to); /* CalcFirstStatement - */ static void CalcFirstStatement (pge_StatementDesc s, pge_ProductionDesc from, pge_SetDesc *to); /* CalcFirstProduction - calculates all of the first symbols for the grammer */ static void CalcFirstProduction (pge_ProductionDesc p, pge_ProductionDesc from, pge_SetDesc *to); static void WorkOutFollowFactor (pge_FactorDesc f, pge_SetDesc *followset, pge_SetDesc after); /* WorkOutFollowTerm - */ static void WorkOutFollowTerm (pge_TermDesc t, pge_SetDesc *followset, pge_SetDesc after); /* WorkOutFollowExpression - */ static void WorkOutFollowExpression (pge_ExpressionDesc e, pge_SetDesc *followset, pge_SetDesc after); /* CollectFollow - collects the follow set from, f, into, to. */ static void CollectFollow (pge_SetDesc *to, pge_FollowDesc f); /* CalcFollowFactor - */ static void CalcFollowFactor (pge_FactorDesc f, pge_SetDesc after); /* CalcFollowTerm - */ static void CalcFollowTerm (pge_TermDesc t, pge_SetDesc after); /* CalcFollowExpression - */ static void CalcFollowExpression (pge_ExpressionDesc e, pge_SetDesc after); /* CalcFollowStatement - given a bnf statement generate the follow set. */ static void CalcFollowStatement (pge_StatementDesc s); /* CalcFollowProduction - */ static void CalcFollowProduction (pge_ProductionDesc p); /* CalcEpsilonFactor - */ static void CalcEpsilonFactor (pge_FactorDesc f); /* CalcEpsilonTerm - */ static void CalcEpsilonTerm (pge_TermDesc t); /* CalcEpsilonExpression - */ static void CalcEpsilonExpression (pge_ExpressionDesc e); /* CalcEpsilonStatement - given a bnf statement generate the follow set. */ static void CalcEpsilonStatement (pge_StatementDesc s); /* CalcEpsilonProduction - */ static void CalcEpsilonProduction (pge_ProductionDesc p); /* CalcReachEndFactor - */ static pge_TraverseResult CalcReachEndFactor (pge_FactorDesc f); /* CalcReachEndTerm - */ static pge_TraverseResult CalcReachEndTerm (pge_TermDesc t); /* CalcReachEndExpression - */ static void CalcReachEndExpression (pge_ExpressionDesc e); /* CalcReachEndStatement - */ static void CalcReachEndStatement (pge_StatementDesc s); /* CalcReachEndStatement - */ static void stop (void); /* CalcReachEndProduction - */ static void CalcReachEndProduction (pge_ProductionDesc p); /* EmptyFactor - */ static bool EmptyFactor (pge_FactorDesc f); /* EmptyTerm - returns TRUE if the term maybe empty. */ static bool EmptyTerm (pge_TermDesc t); /* EmptyExpression - */ static bool EmptyExpression (pge_ExpressionDesc e); /* EmptyStatement - returns TRUE if statement, s, is empty. */ static bool EmptyStatement (pge_StatementDesc s); /* EmptyProduction - returns if production, p, maybe empty. */ static bool EmptyProduction (pge_ProductionDesc p); /* EmitFDLNotice - */ static void EmitFDLNotice (void); /* EmitRules - generates the BNF rules. */ static void EmitRules (void); /* DescribeElement - */ static void DescribeElement (unsigned int name); /* EmitInTestStop - construct a test for stop element, name. */ static void EmitInTestStop (NameKey_Name name); /* DescribeStopElement - */ static void DescribeStopElement (unsigned int name); /* EmitDescribeStop - */ static void EmitDescribeStop (void); /* EmitDescribeError - */ static void EmitDescribeError (void); /* EmitSetTypes - write out the set types used during error recovery */ static void EmitSetTypes (void); /* EmitSupport - generates the support routines. */ static void EmitSupport (void); /* DisposeSetDesc - dispose of the set list, s. */ static void DisposeSetDesc (pge_SetDesc *s); /* OptionalFactor - */ static bool OptionalFactor (pge_FactorDesc f); /* OptionalTerm - returns TRUE if the term maybe empty. */ static bool OptionalTerm (pge_TermDesc t); /* OptionalExpression - */ static bool OptionalExpression (pge_ExpressionDesc e); /* OptionalStatement - returns FALSE if statement, s, does not have a optional ambiguity. */ static bool OptionalStatement (pge_StatementDesc s); /* OptionalProduction - */ static bool OptionalProduction (pge_ProductionDesc p); /* CheckFirstFollow - */ static bool CheckFirstFollow (pge_FactorDesc f, pge_FactorDesc after); /* ConstrainedEmptyFactor - */ static bool ConstrainedEmptyFactor (pge_FactorDesc f); /* ConstrainedEmptyTerm - returns TRUE if the term maybe empty. */ static bool ConstrainedEmptyTerm (pge_TermDesc t); /* ConstrainedEmptyExpression - */ static bool ConstrainedEmptyExpression (pge_ExpressionDesc e); /* ConstrainedEmptyStatement - returns FALSE if statement, s, does not have a optional ambiguity. */ static bool ConstrainedEmptyStatement (pge_StatementDesc s); /* ConstrainedEmptyProduction - returns TRUE if a problem exists with, p. */ static bool ConstrainedEmptyProduction (pge_ProductionDesc p); /* TestForLALR1 - */ static void TestForLALR1 (pge_ProductionDesc p); /* DoEpsilon - runs the epsilon interrelated rules */ static void DoEpsilon (pge_ProductionDesc p); /* CheckComplete - checks that production, p, is complete. */ static void CheckComplete (pge_ProductionDesc p); /* PostProcessRules - backpatch the ident to rule definitions and emit comments and code. */ static void PostProcessRules (void); /* DisplayHelp - display a summary help and then exit (0). */ static void DisplayHelp (void); /* ParseArgs - */ static void ParseArgs (void); /* Init - initialize the modules data structures */ static void Init (void); /* DescribeStop - issues a message explaining what tokens were expected */ static DynamicStrings_String DescribeStop (pge_SetOfStop stopset) { unsigned int n; DynamicStrings_String str; DynamicStrings_String message; n = 0; message = DynamicStrings_InitString ((const char *) "", 0); if ((((1 << (bnflex_literaltok-bnflex_identtok)) & (stopset)) != 0)) { message = DynamicStrings_ConCat (DynamicStrings_ConCatChar (message, ' '), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "literal", 7))); n += 1; } if ((((1 << (bnflex_identtok-bnflex_identtok)) & (stopset)) != 0)) { message = DynamicStrings_ConCat (DynamicStrings_ConCatChar (message, ' '), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "identifier", 10))); n += 1; } if ((((1 << (bnflex_FNBtok-bnflex_identtok)) & (stopset)) != 0)) { message = DynamicStrings_ConCat (DynamicStrings_ConCatChar (message, ' '), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "FNB", 3))); n += 1; } if ((((1 << (bnflex_BNFtok-bnflex_identtok)) & (stopset)) != 0)) { message = DynamicStrings_ConCat (DynamicStrings_ConCatChar (message, ' '), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "BNF", 3))); n += 1; } if ((((1 << (bnflex_epsilontok-bnflex_identtok)) & (stopset)) != 0)) { message = DynamicStrings_ConCat (DynamicStrings_ConCatChar (message, ' '), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "epsilon", 7))); n += 1; } if ((((1 << (bnflex_followtok-bnflex_identtok)) & (stopset)) != 0)) { message = DynamicStrings_ConCat (DynamicStrings_ConCatChar (message, ' '), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "follow", 6))); n += 1; } if ((((1 << (bnflex_firsttok-bnflex_identtok)) & (stopset)) != 0)) { message = DynamicStrings_ConCat (DynamicStrings_ConCatChar (message, ' '), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "first", 5))); n += 1; } if ((((1 << (bnflex_specialtok-bnflex_identtok)) & (stopset)) != 0)) { message = DynamicStrings_ConCat (DynamicStrings_ConCatChar (message, ' '), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "special", 7))); n += 1; } if ((((1 << (bnflex_tokentok-bnflex_identtok)) & (stopset)) != 0)) { message = DynamicStrings_ConCat (DynamicStrings_ConCatChar (message, ' '), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "token", 5))); n += 1; } if ((((1 << (bnflex_declarationtok-bnflex_identtok)) & (stopset)) != 0)) { message = DynamicStrings_ConCat (DynamicStrings_ConCatChar (message, ' '), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "declaration", 11))); n += 1; } if ((((1 << (bnflex_endtok-bnflex_identtok)) & (stopset)) != 0)) { message = DynamicStrings_ConCat (DynamicStrings_ConCatChar (message, ' '), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "end", 3))); n += 1; } if ((((1 << (bnflex_rulestok-bnflex_identtok)) & (stopset)) != 0)) { message = DynamicStrings_ConCat (DynamicStrings_ConCatChar (message, ' '), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "rules", 5))); n += 1; } if ((((1 << (bnflex_begintok-bnflex_identtok)) & (stopset)) != 0)) { message = DynamicStrings_ConCat (DynamicStrings_ConCatChar (message, ' '), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "begin", 5))); n += 1; } if ((((1 << (bnflex_moduletok-bnflex_identtok)) & (stopset)) != 0)) { message = DynamicStrings_ConCat (DynamicStrings_ConCatChar (message, ' '), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "module", 6))); n += 1; } if ((((1 << (bnflex_dquotetok-bnflex_identtok)) & (stopset)) != 0)) { message = DynamicStrings_ConCatChar (DynamicStrings_ConCatChar (DynamicStrings_ConCatChar (DynamicStrings_ConCatChar (DynamicStrings_ConCatChar (message, ' '), '`'), '"'), '\''), ','); n += 1; } if ((((1 << (bnflex_squotetok-bnflex_identtok)) & (stopset)) != 0)) { message = DynamicStrings_ConCatChar (DynamicStrings_ConCatChar (DynamicStrings_ConCatChar (DynamicStrings_ConCatChar (DynamicStrings_ConCatChar (message, ' '), '"'), '\''), '"'), ','); n += 1; } if ((((1 << (bnflex_symfunctok-bnflex_identtok)) & (stopset)) != 0)) { message = DynamicStrings_ConCat (DynamicStrings_ConCatChar (message, ' '), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "symfunc", 7))); n += 1; } if ((((1 << (bnflex_tfunctok-bnflex_identtok)) & (stopset)) != 0)) { message = DynamicStrings_ConCat (DynamicStrings_ConCatChar (message, ' '), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "tokenfunc", 9))); n += 1; } if ((((1 << (bnflex_errortok-bnflex_identtok)) & (stopset)) != 0)) { message = DynamicStrings_ConCat (DynamicStrings_ConCatChar (message, ' '), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "error", 5))); n += 1; } if ((((1 << (bnflex_gretok-bnflex_identtok)) & (stopset)) != 0)) { message = DynamicStrings_ConCat (DynamicStrings_ConCatChar (message, ' '), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) ">", 1))); n += 1; } if ((((1 << (bnflex_lesstok-bnflex_identtok)) & (stopset)) != 0)) { message = DynamicStrings_ConCat (DynamicStrings_ConCatChar (message, ' '), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "<", 1))); n += 1; } if ((((1 << (bnflex_rparatok-bnflex_identtok)) & (stopset)) != 0)) { message = DynamicStrings_ConCat (DynamicStrings_ConCatChar (message, ' '), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) ")", 1))); n += 1; } if ((((1 << (bnflex_lparatok-bnflex_identtok)) & (stopset)) != 0)) { message = DynamicStrings_ConCat (DynamicStrings_ConCatChar (message, ' '), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "(", 1))); n += 1; } if ((((1 << (bnflex_rcparatok-bnflex_identtok)) & (stopset)) != 0)) { message = DynamicStrings_ConCat (DynamicStrings_ConCatChar (message, ' '), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "}", 1))); n += 1; } if ((((1 << (bnflex_lcparatok-bnflex_identtok)) & (stopset)) != 0)) { message = DynamicStrings_ConCat (DynamicStrings_ConCatChar (message, ' '), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "{", 1))); n += 1; } if ((((1 << (bnflex_rsparatok-bnflex_identtok)) & (stopset)) != 0)) { message = DynamicStrings_ConCat (DynamicStrings_ConCatChar (message, ' '), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "]", 1))); n += 1; } if ((((1 << (bnflex_lsparatok-bnflex_identtok)) & (stopset)) != 0)) { message = DynamicStrings_ConCat (DynamicStrings_ConCatChar (message, ' '), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "[", 1))); n += 1; } if ((((1 << (bnflex_bartok-bnflex_identtok)) & (stopset)) != 0)) { message = DynamicStrings_ConCat (DynamicStrings_ConCatChar (message, ' '), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "|", 1))); n += 1; } if ((((1 << (bnflex_rbecomestok-bnflex_identtok)) & (stopset)) != 0)) { message = DynamicStrings_ConCat (DynamicStrings_ConCatChar (message, ' '), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "=:", 2))); n += 1; } if ((((1 << (bnflex_lbecomestok-bnflex_identtok)) & (stopset)) != 0)) { message = DynamicStrings_ConCat (DynamicStrings_ConCatChar (message, ' '), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) ":=", 2))); n += 1; } if ((((1 << (bnflex_codetok-bnflex_identtok)) & (stopset)) != 0)) { message = DynamicStrings_ConCat (DynamicStrings_ConCatChar (message, ' '), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "%", 1))); n += 1; } if ((((1 << (bnflex_eoftok-bnflex_identtok)) & (stopset)) != 0)) {} /* empty. */ /* eoftok has no token name (needed to generate error messages) */ if (n == 0) { str = DynamicStrings_InitString ((const char *) " syntax error", 13); message = DynamicStrings_KillString (message); } else if (n == 1) { /* avoid dangling else. */ str = DynamicStrings_ConCat (message, DynamicStrings_Mark (DynamicStrings_InitString ((const char *) " missing ", 9))); } else { /* avoid dangling else. */ str = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) " expecting one of", 17), message); message = DynamicStrings_KillString (message); } return str; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* DescribeError - issues a message explaining what tokens were expected */ static void DescribeError (void) { DynamicStrings_String str; str = DynamicStrings_InitString ((const char *) "", 0); switch (bnflex_GetCurrentTokenType ()) { case bnflex_literaltok: str = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "syntax error, found literal", 27), DynamicStrings_Mark (str)); break; case bnflex_identtok: str = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "syntax error, found identifier", 30), DynamicStrings_Mark (str)); break; case bnflex_FNBtok: str = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "syntax error, found FNB", 23), DynamicStrings_Mark (str)); break; case bnflex_BNFtok: str = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "syntax error, found BNF", 23), DynamicStrings_Mark (str)); break; case bnflex_epsilontok: str = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "syntax error, found epsilon", 27), DynamicStrings_Mark (str)); break; case bnflex_followtok: str = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "syntax error, found follow", 26), DynamicStrings_Mark (str)); break; case bnflex_firsttok: str = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "syntax error, found first", 25), DynamicStrings_Mark (str)); break; case bnflex_specialtok: str = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "syntax error, found special", 27), DynamicStrings_Mark (str)); break; case bnflex_tokentok: str = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "syntax error, found token", 25), DynamicStrings_Mark (str)); break; case bnflex_declarationtok: str = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "syntax error, found declaration", 31), DynamicStrings_Mark (str)); break; case bnflex_endtok: str = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "syntax error, found end", 23), DynamicStrings_Mark (str)); break; case bnflex_rulestok: str = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "syntax error, found rules", 25), DynamicStrings_Mark (str)); break; case bnflex_begintok: str = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "syntax error, found begin", 25), DynamicStrings_Mark (str)); break; case bnflex_moduletok: str = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "syntax error, found module", 26), DynamicStrings_Mark (str)); break; case bnflex_dquotetok: str = DynamicStrings_ConCat (DynamicStrings_ConCatChar (DynamicStrings_ConCatChar (DynamicStrings_InitString ((const char *) "syntax error, found '", 21), '"'), '\''), DynamicStrings_Mark (str)); break; case bnflex_squotetok: str = DynamicStrings_ConCat (DynamicStrings_ConCatChar (DynamicStrings_ConCatChar (DynamicStrings_InitString ((const char *) "syntax error, found \"", 21), '\''), '"'), DynamicStrings_Mark (str)); break; case bnflex_symfunctok: str = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "syntax error, found symfunc", 27), DynamicStrings_Mark (str)); break; case bnflex_tfunctok: str = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "syntax error, found tokenfunc", 29), DynamicStrings_Mark (str)); break; case bnflex_errortok: str = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "syntax error, found error", 25), DynamicStrings_Mark (str)); break; case bnflex_gretok: str = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "syntax error, found >", 21), DynamicStrings_Mark (str)); break; case bnflex_lesstok: str = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "syntax error, found <", 21), DynamicStrings_Mark (str)); break; case bnflex_rparatok: str = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "syntax error, found )", 21), DynamicStrings_Mark (str)); break; case bnflex_lparatok: str = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "syntax error, found (", 21), DynamicStrings_Mark (str)); break; case bnflex_rcparatok: str = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "syntax error, found }", 21), DynamicStrings_Mark (str)); break; case bnflex_lcparatok: str = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "syntax error, found {", 21), DynamicStrings_Mark (str)); break; case bnflex_rsparatok: str = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "syntax error, found ]", 21), DynamicStrings_Mark (str)); break; case bnflex_lsparatok: str = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "syntax error, found [", 21), DynamicStrings_Mark (str)); break; case bnflex_bartok: str = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "syntax error, found |", 21), DynamicStrings_Mark (str)); break; case bnflex_rbecomestok: str = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "syntax error, found =:", 22), DynamicStrings_Mark (str)); break; case bnflex_lbecomestok: str = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "syntax error, found :=", 22), DynamicStrings_Mark (str)); break; case bnflex_codetok: str = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "syntax error, found %", 21), DynamicStrings_Mark (str)); break; case bnflex_eoftok: str = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "syntax error, found ", 20), DynamicStrings_Mark (str)); break; default: break; } PushBackInput_WarnString (str); } /* AddEntry - adds an entry into, t, containing [def:value]. */ static void AddEntry (SymbolKey_SymbolTree *t, NameKey_Name def, NameKey_Name value) { if (SymbolKey_ContainsSymKey ((*t), def)) { WarnError1 ((const char *) "already seen a definition for token '%s'", 40, def); } else { SymbolKey_PutSymKey ((*t), def, value); } } /* Format1 - converts string, src, into, dest, together with encapsulated entity, n. It only formats the first %s or %d with n. */ static void Format1 (const char *src_, unsigned int _src_high, unsigned int n, char *dest, unsigned int _dest_high) { typedef struct Format1__T12_a Format1__T12; struct Format1__T12_a { char array[MaxString+1]; }; unsigned int HighSrc; unsigned int HighDest; unsigned int i; unsigned int j; Format1__T12 str; char src[_src_high+1]; /* make a local copy of each unbounded array. */ memcpy (src, src_, _src_high+1); HighSrc = StrLib_StrLen ((const char *) src, _src_high); HighDest = _dest_high; i = 0; j = 0; while ((((i < HighSrc) && (src[i] != ASCII_nul)) && (j < HighDest)) && (src[i] != '%')) { dest[j] = src[i]; i += 1; j += 1; } if ((((i+1) < HighSrc) && (src[i] == '%')) && (j < HighDest)) { /* avoid gcc warning by using compound statement even if not strictly necessary. */ if (src[i+1] == 's') { dest[j] = ASCII_nul; NameKey_GetKey (n, (char *) &str.array[0], MaxString); StrLib_StrConCat ((const char *) dest, _dest_high, (const char *) &str.array[0], MaxString, (char *) dest, _dest_high); j = StrLib_StrLen ((const char *) dest, _dest_high); i += 2; } else if (src[i+1] == 'd') { /* avoid dangling else. */ dest[j] = ASCII_nul; NumberIO_CardToStr (n, 0, (char *) &str.array[0], MaxString); StrLib_StrConCat ((const char *) dest, _dest_high, (const char *) &str.array[0], MaxString, (char *) dest, _dest_high); j = StrLib_StrLen ((const char *) dest, _dest_high); i += 2; } else { /* avoid dangling else. */ dest[j] = src[i]; i += 1; j += 1; } } /* and finish off copying src into dest */ while (((i < HighSrc) && (src[i] != ASCII_nul)) && (j < HighDest)) { dest[j] = src[i]; i += 1; j += 1; } if (j < HighDest) { dest[j] = ASCII_nul; } } /* WarnError1 - */ static void WarnError1 (const char *a_, unsigned int _a_high, unsigned int n) { typedef struct WarnError1__T13_a WarnError1__T13; struct WarnError1__T13_a { char array[MaxString+1]; }; WarnError1__T13 line; char a[_a_high+1]; /* make a local copy of each unbounded array. */ memcpy (a, a_, _a_high+1); Format1 ((const char *) a, _a_high, n, (char *) &line.array[0], MaxString); PushBackInput_WarnError ((const char *) &line.array[0], MaxString); } /* PrettyFollow - */ static void PrettyFollow (const char *start_, unsigned int _start_high, const char *end_, unsigned int _end_high, pge_FollowDesc f) { char start[_start_high+1]; char end[_end_high+1]; /* make a local copy of each unbounded array. */ memcpy (start, start_, _start_high+1); memcpy (end, end_, _end_high+1); if (Debugging) { Output_WriteString ((const char *) start, _start_high); if (f != NULL) { if (f->calcfollow) { Output_WriteString ((const char *) "followset defined as:", 21); EmitSet (f->follow, static_cast (0), static_cast (0)); } switch (f->reachend) { case pge_true: Output_WriteString ((const char *) " [E]", 4); break; case pge_false: Output_WriteString ((const char *) " [C]", 4); break; case pge_unknown: Output_WriteString ((const char *) " [U]", 4); break; default: break; } switch (f->epsilon) { case pge_true: Output_WriteString ((const char *) " [e]", 4); break; case pge_false: break; case pge_unknown: Output_WriteString ((const char *) " [u]", 4); break; default: break; } } Output_WriteString ((const char *) end, _end_high); } } /* NewFollow - creates a new follow descriptor and returns the data structure. */ static pge_FollowDesc NewFollow (void) { pge_FollowDesc f; Storage_ALLOCATE ((void **) &f, sizeof (pge__T6)); f->follow = NULL; f->reachend = pge_unknown; f->epsilon = pge_unknown; return f; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* AssignEpsilon - assigns the epsilon value and sets the epsilon to value, providing condition is TRUE. */ static void AssignEpsilon (bool condition, pge_FollowDesc f, pge_TraverseResult value) { if ((condition && (value != pge_unknown)) && (f->epsilon == pge_unknown)) { f->epsilon = value; Finished = false; } } /* GetEpsilon - returns the value of epsilon */ static pge_TraverseResult GetEpsilon (pge_FollowDesc f) { if (f == NULL) { Debug_Halt ((const char *) "why is the follow info NIL?", 27, (const char *) "m2/gm2-auto/pge.mod", 19, (const char *) "GetEpsilon", 10, 597); } else { return f->epsilon; } ReturnException ("m2/gm2-auto/pge.mod", 1, 7); __builtin_unreachable (); } /* AssignReachEnd - assigns the reachend value providing that, condition, is TRUE. */ static void AssignReachEnd (bool condition, pge_FollowDesc f, pge_TraverseResult value) { if (condition) { if ((f->reachend == pge_unknown) && (value != pge_unknown)) { f->reachend = value; Finished = false; } } } /* GetReachEnd - returns the value of reachend */ static pge_TraverseResult GetReachEnd (pge_FollowDesc f) { if (f == NULL) { Debug_Halt ((const char *) "why is the follow info NIL?", 27, (const char *) "m2/gm2-auto/pge.mod", 19, (const char *) "GetReachEnd", 11, 632); } else { return f->reachend; } ReturnException ("m2/gm2-auto/pge.mod", 1, 7); __builtin_unreachable (); } /* AssignFollow - assigns the follow set and sets the calcfollow to TRUE. */ static void AssignFollow (pge_FollowDesc f, pge_SetDesc s) { if (f->calcfollow) { Debug_Halt ((const char *) "why are we reassigning this follow set?", 39, (const char *) "m2/gm2-auto/pge.mod", 19, (const char *) "AssignFollow", 12, 649); } f->follow = s; f->calcfollow = true; } /* GetFollow - returns the follow set. */ static pge_SetDesc GetFollow (pge_FollowDesc f) { if (f == NULL) { Debug_Halt ((const char *) "why is the follow info NIL?", 27, (const char *) "m2/gm2-auto/pge.mod", 19, (const char *) "GetFollow", 9, 666); } else { if (f->calcfollow) { return f->follow; } else { Debug_Halt ((const char *) "not calculated the follow set yet..", 35, (const char *) "m2/gm2-auto/pge.mod", 19, (const char *) "GetFollow", 9, 674); } } ReturnException ("m2/gm2-auto/pge.mod", 1, 7); __builtin_unreachable (); } /* NewProduction - creates a new production and returns the data structure. */ static pge_ProductionDesc NewProduction (void) { pge_ProductionDesc p; Storage_ALLOCATE ((void **) &p, sizeof (pge__T2)); if (TailProduction != NULL) { TailProduction->next = p; } TailProduction = p; if (HeadProduction == NULL) { HeadProduction = p; } p->next = NULL; p->statement = NULL; p->first = NULL; p->firstsolved = false; p->followinfo = NewFollow (); p->line = PushBackInput_GetCurrentLine (); p->description = NameKey_NulName; return p; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* NewFactor - */ static pge_FactorDesc NewFactor (void) { pge_FactorDesc f; Storage_ALLOCATE ((void **) &f, sizeof (pge__T5)); f->next = NULL; f->followinfo = NewFollow (); f->line = PushBackInput_GetCurrentLine (); return f; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* NewTerm - returns a new term. */ static pge_TermDesc NewTerm (void) { pge_TermDesc t; Storage_ALLOCATE ((void **) &t, sizeof (pge_termdesc)); t->factor = NULL; t->followinfo = NewFollow (); t->next = NULL; t->line = PushBackInput_GetCurrentLine (); return t; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* NewExpression - returns a new expression. */ static pge_ExpressionDesc NewExpression (void) { pge_ExpressionDesc e; Storage_ALLOCATE ((void **) &e, sizeof (pge__T4)); e->term = NULL; e->followinfo = NewFollow (); e->line = PushBackInput_GetCurrentLine (); return e; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* NewStatement - returns a new statement. */ static pge_StatementDesc NewStatement (void) { pge_StatementDesc s; Storage_ALLOCATE ((void **) &s, sizeof (pge__T3)); s->ident = NULL; s->expr = NULL; s->followinfo = NewFollow (); s->line = PushBackInput_GetCurrentLine (); return s; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* NewSetDesc - creates a new set description and returns the data structure. */ static pge_SetDesc NewSetDesc (void) { pge_SetDesc s; Storage_ALLOCATE ((void **) &s, sizeof (pge__T7)); s->next = NULL; return s; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* NewCodeDesc - creates a new code descriptor and initializes all fields to zero. */ static pge_CodeDesc NewCodeDesc (void) { pge_CodeDesc c; Storage_ALLOCATE ((void **) &c, sizeof (pge__T8)); c->code = NULL; c->indent = 0; c->line = PushBackInput_GetCurrentLine (); return c; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* CodeFragmentPrologue - consumes code text up to a "%" after a newline. */ static void CodeFragmentPrologue (void) { LinePrologue = PushBackInput_GetCurrentLine (); GetCodeFragment (&CodePrologue); } /* CodeFragmentEpilogue - consumes code text up to a "%" after a newline. */ static void CodeFragmentEpilogue (void) { LineEpilogue = PushBackInput_GetCurrentLine (); GetCodeFragment (&CodeEpilogue); } /* CodeFragmentDeclaration - consumes code text up to a "%" after a newline. */ static void CodeFragmentDeclaration (void) { LineDeclaration = PushBackInput_GetCurrentLine (); GetCodeFragment (&CodeDeclaration); } /* GetCodeFragment - collects the code fragment up until ^ % */ static void GetCodeFragment (pge_CodeHunk *h) { unsigned int i; char ch; (*h) = NULL; i = 0; while (((bnflex_PutChar (bnflex_GetChar ())) != '%') && ((bnflex_PutChar (bnflex_GetChar ())) != ASCII_nul)) { do { while (((bnflex_PutChar (bnflex_GetChar ())) != ASCII_nul) && ((bnflex_PutChar (bnflex_GetChar ())) != ASCII_lf)) { (*h) = Add (h, bnflex_GetChar (), &i); } if ((bnflex_PutChar (bnflex_GetChar ())) == ASCII_lf) { /* consume line feed */ (*h) = Add (h, bnflex_GetChar (), &i); ch = bnflex_PutChar (ASCII_lf); } else if ((bnflex_PutChar (bnflex_GetChar ())) == ASCII_nul) { /* avoid dangling else. */ ch = bnflex_PutChar (ASCII_nul); ch = bnflex_PutChar (ASCII_lf); } else { /* avoid dangling else. */ ch = bnflex_PutChar (bnflex_PutChar (bnflex_GetChar ())); } } while (! ((bnflex_GetChar ()) == ASCII_lf)); } if ((bnflex_PutChar (bnflex_GetChar ())) == '%') { (*h) = Add (h, ASCII_nul, &i); ch = bnflex_PutChar (' '); /* to give the following token % a delimiter infront of it */ bnflex_AdvanceToken (); /* to give the following token % a delimiter infront of it */ } else { PushBackInput_WarnError ((const char *) "expecting % to terminate code fragment, found end of file", 57); } } /* WriteCodeHunkList - writes the CodeHunk list in the correct order. */ static void WriteCodeHunkList (pge_CodeHunk l) { if (l != NULL) { OnLineStart = false; /* recursion */ WriteCodeHunkList (l->next); Output_WriteString ((const char *) &l->codetext.array[0], MaxCodeHunkLength); } } /* WriteIndent - writes, n, spaces. */ static void WriteIndent (unsigned int n) { while (n > 0) { Output_Write (' '); n -= 1; } OnLineStart = false; } /* CheckWrite - */ static void CheckWrite (char ch, unsigned int *curpos, unsigned int left, bool *seentext) { if (ch == ASCII_lf) { NewLine (left); (*curpos) = 0; (*seentext) = false; } else { Output_Write (ch); (*curpos) += 1; } } /* WriteStringIndent - writes a string but it will try and remove upto indent spaces if they exist. */ static void WriteStringIndent (const char *a_, unsigned int _a_high, unsigned int indent, unsigned int *curpos, unsigned int left, bool *seentext) { unsigned int l; unsigned int i; char a[_a_high+1]; /* make a local copy of each unbounded array. */ memcpy (a, a_, _a_high+1); i = 0; l = StrLib_StrLen ((const char *) a, _a_high); while (i < l) { if ((*seentext)) { CheckWrite (a[i], curpos, left, seentext); } else { if (a[i] == ' ') { /* ignore space for now */ (*curpos) += 1; } else { if ((*curpos) >= indent) { WriteIndent ((*curpos)-indent); } (*seentext) = true; CheckWrite (a[i], curpos, left, seentext); } } i += 1; } } /* WriteCodeHunkListIndent - writes the CodeHunk list in the correct order but it removes up to indent spaces if they exist. */ static void WriteCodeHunkListIndent (pge_CodeHunk l, unsigned int indent, unsigned int *curpos, unsigned int left, bool *seentext) { if (l != NULL) { /* recursion */ WriteCodeHunkListIndent (l->next, indent, curpos, left, seentext); WriteStringIndent ((const char *) &l->codetext.array[0], MaxCodeHunkLength, indent, curpos, left, seentext); } } /* Add - adds a character to a code hunk and creates another code hunk if necessary. */ static pge_CodeHunk Add (pge_CodeHunk *p, char ch, unsigned int *i) { pge_CodeHunk q; if (((*p) == NULL) || ((*i) > MaxCodeHunkLength)) { Storage_ALLOCATE ((void **) &q, sizeof (pge__T9)); q->next = (*p); q->codetext.array[0] = ch; (*i) = 1; return q; } else { (*p)->codetext.array[(*i)] = ch; (*i) += 1; return (*p); } /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* ConsHunk - combine two possible code hunks. */ static void ConsHunk (pge_CodeHunk *p, pge_CodeHunk q) { pge_CodeHunk r; if ((*p) != NULL) { r = q; while (r->next != NULL) { r = r->next; } r->next = (*p); } (*p) = q; } /* GetName - returns the next symbol which is checked for a legal name. */ static NameKey_Name GetName (void) { NameKey_Name name; if (bnflex_IsReserved (bnflex_GetCurrentToken ())) { PushBackInput_WarnError ((const char *) "expecting a name and found a reserved word", 42); bnflex_AdvanceToken (); /* move on to another token */ return NameKey_NulName; /* move on to another token */ } else { name = bnflex_GetCurrentToken (); bnflex_AdvanceToken (); return name; } /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* SyntaxError - after a syntax error we skip all tokens up until we reach a stop symbol. */ static void SyntaxError (pge_SetOfStop stop) { DescribeError (); if (Debugging) { StrIO_WriteLn (); StrIO_WriteString ((const char *) "skipping token *** ", 19); } while (! ((((1 << (bnflex_GetCurrentTokenType ()-bnflex_identtok)) & (stop)) != 0))) { bnflex_AdvanceToken (); } if (Debugging) { StrIO_WriteString ((const char *) " ***", 4); StrIO_WriteLn (); } WasNoError = false; } /* SyntaxCheck - */ static void SyntaxCheck (pge_SetOfStop stop) { if (! ((((1 << (bnflex_GetCurrentTokenType ()-bnflex_identtok)) & (stop)) != 0))) { SyntaxError (stop); } } /* Expect - */ static void Expect (bnflex_TokenType t, pge_SetOfStop stop) { if ((bnflex_GetCurrentTokenType ()) == t) { bnflex_AdvanceToken (); } else { SyntaxError (stop); } SyntaxCheck (stop); } /* Ident - error checking varient of Ident */ static void Ident (pge_SetOfStop stop) { if ((bnflex_GetCurrentTokenType ()) == bnflex_identtok) { Storage_ALLOCATE ((void **) &CurrentIdent, sizeof (pge__T1)); CurrentIdent->definition = NULL; CurrentIdent->name = GetName (); CurrentIdent->line = PushBackInput_GetCurrentLine (); } } /* Modula2Code - error checking varient of Modula2Code */ static void Modula2Code (pge_SetOfStop stop) { pge_CodeHunk p; unsigned int i; bool quote; unsigned int line; unsigned int position; line = PushBackInput_GetCurrentLine (); bnflex_PushBackToken (bnflex_GetCurrentToken ()); position = PushBackInput_GetColumnPosition (); p = NULL; bnflex_SkipWhite (); while (((bnflex_PutChar (bnflex_GetChar ())) != '%') && ((bnflex_PutChar (bnflex_GetChar ())) != ASCII_nul)) { if ((bnflex_PutChar (bnflex_GetChar ())) == '"') { /* avoid dangling else. */ do { p = Add (&p, bnflex_GetChar (), &i); } while (! (((bnflex_PutChar (bnflex_GetChar ())) == '"') || ((bnflex_PutChar (bnflex_GetChar ())) == ASCII_nul))); p = Add (&p, '"', &i); if (((bnflex_PutChar (bnflex_GetChar ())) == '"') && ((bnflex_GetChar ()) == '"')) {} /* empty. */ } else if ((bnflex_PutChar (bnflex_GetChar ())) == '\'') { /* avoid dangling else. */ do { p = Add (&p, bnflex_GetChar (), &i); } while (! (((bnflex_PutChar (bnflex_GetChar ())) == '\'') || ((bnflex_PutChar (bnflex_GetChar ())) == ASCII_nul))); p = Add (&p, '\'', &i); if (((bnflex_PutChar (bnflex_GetChar ())) == '\'') && ((bnflex_GetChar ()) == '\'')) {} /* empty. */ } else if (((bnflex_PutChar (bnflex_GetChar ())) == '\\') && ((bnflex_GetChar ()) == '\\')) { /* avoid dangling else. */ p = Add (&p, bnflex_GetChar (), &i); } else if ((bnflex_PutChar (bnflex_GetChar ())) != '%') { /* avoid dangling else. */ p = Add (&p, bnflex_GetChar (), &i); } } p = Add (&p, ASCII_nul, &i); CurrentFactor->type = pge_m2; CurrentFactor->code = NewCodeDesc (); CurrentFactor->code->code = p; CurrentFactor->code->indent = position; if ((bnflex_PutChar (' ')) == ' ') {} /* empty. */ bnflex_AdvanceToken (); /* read the next token ready for the parser */ if (! WasNoError) /* read the next token ready for the parser */ { WarnError1 ((const char *) "error probably occurred before the start of inline code on line %d", 66, line); } } /* StartModName := % ModuleName := GetName() ; ignore begintok CodeFragmentPrologue % =: */ static void StartModName (pge_SetOfStop stop) { ModuleName = GetName (); CodeFragmentPrologue (); } /* EndModName := */ static void EndModName (pge_SetOfStop stop) { if (ModuleName != (GetName ())) { PushBackInput_WarnError ((const char *) "expecting same module name at end as beginning", 46); } /* ignore endtok as it consumes the token afterwards */ CodeFragmentEpilogue (); } /* DoDeclaration := % CodeFragmentDeclaration % =: */ static void DoDeclaration (pge_SetOfStop stop) { if (ModuleName != (GetName ())) { PushBackInput_WarnError ((const char *) "expecting same module name in declaration as in the beginning", 61); } /* ignore begintok as it consumes the token afterwards */ CodeFragmentDeclaration (); } /* CollectLiteral := % LastLiteral := GetCurrentToken() ; AdvanceToken ; % first symbols:literaltok cannot reachend */ static void CollectLiteral (pge_SetOfStop stopset) { LastLiteral = bnflex_GetCurrentToken (); /* */ bnflex_AdvanceToken (); } /* CollectTok := % CurrentSetDesc := NewSetDesc() ; WITH CurrentSetDesc^ DO type := tokel ; string := GetCurrentToken() ; END ; IF NOT ContainsSymKey(Values, GetCurrentToken()) THEN AddEntry(Values, GetCurrentToken(), LargestValue) ; AddEntry(ReverseValues, Name(LargestValue), GetCurrentToken()) ; AddEntry(Aliases, GetCurrentToken(), GetCurrentToken()) ; AddEntry(ReverseAliases, GetCurrentToken(), GetCurrentToken()) ; INC(LargestValue) END ; AdvanceToken() ; % first symbols:identtok cannot reachend */ static void CollectTok (pge_SetOfStop stopset) { CurrentSetDesc = NewSetDesc (); /* */ CurrentSetDesc->type = pge_tokel; CurrentSetDesc->string = bnflex_GetCurrentToken (); if (! (SymbolKey_ContainsSymKey (Values, bnflex_GetCurrentToken ()))) { AddEntry (&Values, bnflex_GetCurrentToken (), LargestValue); AddEntry (&ReverseValues, (NameKey_Name) (LargestValue), bnflex_GetCurrentToken ()); AddEntry (&Aliases, bnflex_GetCurrentToken (), bnflex_GetCurrentToken ()); AddEntry (&ReverseAliases, bnflex_GetCurrentToken (), bnflex_GetCurrentToken ()); LargestValue += 1; } bnflex_AdvanceToken (); } /* DefineToken := % AddEntry(Aliases, LastLiteral, GetCurrentToken()) ; AddEntry(ReverseAliases, GetCurrentToken(), LastLiteral) ; AddEntry(Values, GetCurrentToken(), LargestValue) ; AddEntry(ReverseValues, Name(LargestValue), GetCurrentToken()) ; INC(LargestValue) ; AdvanceToken ; % first symbols:identtok cannot reachend */ static void DefineToken (pge_SetOfStop stopset) { AddEntry (&Aliases, LastLiteral, bnflex_GetCurrentToken ()); /* */ AddEntry (&ReverseAliases, bnflex_GetCurrentToken (), LastLiteral); AddEntry (&Values, bnflex_GetCurrentToken (), LargestValue); AddEntry (&ReverseValues, (NameKey_Name) (LargestValue), bnflex_GetCurrentToken ()); LargestValue += 1; bnflex_AdvanceToken (); } /* Rules := '%' 'rules' { Defs } ExtBNF first symbols:codetok cannot reachend */ static void Rules (pge_SetOfStop stopset) { Expect (bnflex_codetok, stopset|(pge_SetOfStop) ((1 << (bnflex_rulestok-bnflex_identtok)))); 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)))); while ((((1 << (bnflex_GetCurrentTokenType ())) & ((unsigned int) ((1 << (bnflex_specialtok)) | (1 << (bnflex_tokentok)) | (1 << (bnflex_errortok)) | (1 << (bnflex_tfunctok)) | (1 << (bnflex_symfunctok))))) != 0)) { 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)))); } /* while */ ExtBNF (stopset); } /* Special := Ident % VAR p: ProductionDesc ; % % p := NewProduction() ; p^.statement := NewStatement() ; p^.statement^.followinfo^.calcfollow := TRUE ; p^.statement^.followinfo^.epsilon := false ; p^.statement^.followinfo^.reachend := false ; p^.statement^.ident := CurrentIdent ; p^.statement^.expr := NIL ; p^.firstsolved := TRUE ; p^.followinfo^.calcfollow := TRUE ; p^.followinfo^.epsilon := false ; p^.followinfo^.reachend := false % First Follow [ 'epsilon' % p^.statement^.followinfo^.epsilon := true ; these are not used - but they are displayed when debugging p^.statement^.followinfo^.reachend := true ; p^.followinfo^.epsilon := true ; p^.followinfo^.reachend := true % ] [ Literal % p^.description := LastLiteral % ] first symbols:identtok cannot reachend */ static void Special (pge_SetOfStop stopset) { pge_ProductionDesc p; Ident (stopset|(pge_SetOfStop) ((1 << (bnflex_firsttok-bnflex_identtok)))); p = NewProduction (); p->statement = NewStatement (); p->statement->followinfo->calcfollow = true; p->statement->followinfo->epsilon = pge_false; p->statement->followinfo->reachend = pge_false; p->statement->ident = CurrentIdent; p->statement->expr = NULL; p->firstsolved = true; p->followinfo->calcfollow = true; p->followinfo->epsilon = pge_false; p->followinfo->reachend = pge_false; First (stopset|(pge_SetOfStop) ((1 << (bnflex_followtok-bnflex_identtok)))); Follow (stopset|(pge_SetOfStop) ((1 << (bnflex_epsilontok-bnflex_identtok)) | (1 << (bnflex_squotetok-bnflex_identtok)) | (1 << (bnflex_dquotetok-bnflex_identtok)))); if ((bnflex_GetCurrentTokenType ()) == bnflex_epsilontok) { Expect (bnflex_epsilontok, stopset|(pge_SetOfStop) ((1 << (bnflex_dquotetok-bnflex_identtok)) | (1 << (bnflex_squotetok-bnflex_identtok)))); p->statement->followinfo->epsilon = pge_true; /* these are not used - but they are displayed when debugging */ p->statement->followinfo->reachend = pge_true; /* these are not used - but they are displayed when debugging */ p->followinfo->epsilon = pge_true; p->followinfo->reachend = pge_true; } if ((((1 << (bnflex_GetCurrentTokenType ())) & ((unsigned int) ((1 << (bnflex_dquotetok)) | (1 << (bnflex_squotetok))))) != 0)) { Literal (stopset); p->description = LastLiteral; } } /* Factor := '%' Modula2Code '%' | Ident % WITH CurrentFactor^ DO type := id ; ident := CurrentIdent END ; % | Literal % WITH CurrentFactor^ DO type := lit ; string := LastLiteral ; IF GetSymKey(Aliases, LastLiteral)=NulName THEN WarnError1('no token defined for literal %s', LastLiteral) END END ; % | '{' % WITH CurrentFactor^ DO type := mult ; expr := NewExpression() ; CurrentExpression := expr ; END ; % Expression '}' | '[' % WITH CurrentFactor^ DO type := opt ; expr := NewExpression() ; CurrentExpression := expr ; END ; % Expression ']' | '(' % WITH CurrentFactor^ DO type := sub ; expr := NewExpression() ; CurrentExpression := expr ; END ; % Expression ')' first symbols:dquotetok, squotetok, lparatok, lsparatok, lcparatok, identtok, codetok cannot reachend */ static void Factor (pge_SetOfStop stopset) { if ((bnflex_GetCurrentTokenType ()) == bnflex_codetok) { Expect (bnflex_codetok, stopset); Modula2Code (stopset|(pge_SetOfStop) ((1 << (bnflex_codetok-bnflex_identtok)))); Expect (bnflex_codetok, stopset); } else if ((bnflex_GetCurrentTokenType ()) == bnflex_identtok) { /* avoid dangling else. */ Ident (stopset); CurrentFactor->type = pge_id; CurrentFactor->ident = CurrentIdent; } else if ((((1 << (bnflex_GetCurrentTokenType ())) & ((unsigned int) ((1 << (bnflex_dquotetok)) | (1 << (bnflex_squotetok))))) != 0)) { /* avoid dangling else. */ Literal (stopset); CurrentFactor->type = pge_lit; CurrentFactor->string = LastLiteral; if ((SymbolKey_GetSymKey (Aliases, LastLiteral)) == NameKey_NulName) { WarnError1 ((const char *) "no token defined for literal %s", 31, LastLiteral); } } else if ((bnflex_GetCurrentTokenType ()) == bnflex_lcparatok) { /* avoid dangling else. */ 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)))); CurrentFactor->type = pge_mult; CurrentFactor->expr = NewExpression (); CurrentExpression = CurrentFactor->expr; Expression (stopset|(pge_SetOfStop) ((1 << (bnflex_rcparatok-bnflex_identtok)))); Expect (bnflex_rcparatok, stopset); } else if ((bnflex_GetCurrentTokenType ()) == bnflex_lsparatok) { /* avoid dangling else. */ 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)))); CurrentFactor->type = pge_opt; CurrentFactor->expr = NewExpression (); CurrentExpression = CurrentFactor->expr; Expression (stopset|(pge_SetOfStop) ((1 << (bnflex_rsparatok-bnflex_identtok)))); Expect (bnflex_rsparatok, stopset); } else if ((bnflex_GetCurrentTokenType ()) == bnflex_lparatok) { /* avoid dangling else. */ 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)))); CurrentFactor->type = pge_sub; CurrentFactor->expr = NewExpression (); CurrentExpression = CurrentFactor->expr; Expression (stopset|(pge_SetOfStop) ((1 << (bnflex_rparatok-bnflex_identtok)))); Expect (bnflex_rparatok, stopset); } else { /* avoid dangling else. */ PushBackInput_WarnError ((const char *) "expecting one of: ( [ { \" single quote identifier %", 51); } } /* Statement := % VAR i: IdentDesc ; % Ident % VAR p: ProductionDesc ; % % p := FindDefinition(CurrentIdent^.name) ; IF p=NIL THEN p := NewProduction() ELSE IF NOT ((p^.statement=NIL) OR (p^.statement^.expr=NIL)) THEN WarnError1('already declared rule %s', CurrentIdent^.name) END END ; i := CurrentIdent ; % ':=' % VAR e: ExpressionDesc ; % % e := NewExpression() ; CurrentExpression := e ; % % VAR s: StatementDesc ; % % s := NewStatement() ; WITH s^ DO ident := i ; expr := e END ; % Expression % p^.statement := s ; % '=:' first symbols:identtok cannot reachend */ static void Statement (pge_SetOfStop stopset) { pge_IdentDesc i; pge_ProductionDesc p; pge_ExpressionDesc e; pge_StatementDesc s; Ident (stopset|(pge_SetOfStop) ((1 << (bnflex_lbecomestok-bnflex_identtok)))); p = FindDefinition (CurrentIdent->name); if (p == NULL) { p = NewProduction (); } else { if (! ((p->statement == NULL) || (p->statement->expr == NULL))) { WarnError1 ((const char *) "already declared rule %s", 24, CurrentIdent->name); } } i = CurrentIdent; 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)))); e = NewExpression (); CurrentExpression = e; s = NewStatement (); s->ident = i; s->expr = e; Expression (stopset|(pge_SetOfStop) ((1 << (bnflex_rbecomestok-bnflex_identtok)))); p->statement = s; Expect (bnflex_rbecomestok, stopset); } /* Defs := 'special' Special | 'token' Token | 'error' ErrorProcedures | 'tokenfunc' TokenProcedure | 'symfunc' SymProcedure first symbols:symfunctok, tfunctok, errortok, tokentok, specialtok cannot reachend */ static void Defs (pge_SetOfStop stopset) { if ((bnflex_GetCurrentTokenType ()) == bnflex_specialtok) { Expect (bnflex_specialtok, stopset|(pge_SetOfStop) ((1 << (bnflex_identtok-bnflex_identtok)))); Special (stopset); } else if ((bnflex_GetCurrentTokenType ()) == bnflex_tokentok) { /* avoid dangling else. */ Expect (bnflex_tokentok, stopset|(pge_SetOfStop) ((1 << (bnflex_dquotetok-bnflex_identtok)) | (1 << (bnflex_squotetok-bnflex_identtok)))); Token (stopset); } else if ((bnflex_GetCurrentTokenType ()) == bnflex_errortok) { /* avoid dangling else. */ Expect (bnflex_errortok, stopset|(pge_SetOfStop) ((1 << (bnflex_dquotetok-bnflex_identtok)) | (1 << (bnflex_squotetok-bnflex_identtok)))); ErrorProcedures (stopset); } else if ((bnflex_GetCurrentTokenType ()) == bnflex_tfunctok) { /* avoid dangling else. */ Expect (bnflex_tfunctok, stopset|(pge_SetOfStop) ((1 << (bnflex_dquotetok-bnflex_identtok)) | (1 << (bnflex_squotetok-bnflex_identtok)))); TokenProcedure (stopset); } else if ((bnflex_GetCurrentTokenType ()) == bnflex_symfunctok) { /* avoid dangling else. */ Expect (bnflex_symfunctok, stopset|(pge_SetOfStop) ((1 << (bnflex_dquotetok-bnflex_identtok)) | (1 << (bnflex_squotetok-bnflex_identtok)))); SymProcedure (stopset); } else { /* avoid dangling else. */ PushBackInput_WarnError ((const char *) "expecting one of: symfunc tokenfunc error token special", 55); } } /* ExtBNF := 'BNF' { Production } 'FNB' first symbols:BNFtok cannot reachend */ static void ExtBNF (pge_SetOfStop stopset) { Expect (bnflex_BNFtok, stopset|(pge_SetOfStop) ((1 << (bnflex_FNBtok-bnflex_identtok)) | (1 << (bnflex_identtok-bnflex_identtok)))); while ((bnflex_GetCurrentTokenType ()) == bnflex_identtok) { Production (stopset|(pge_SetOfStop) ((1 << (bnflex_FNBtok-bnflex_identtok)) | (1 << (bnflex_identtok-bnflex_identtok)))); } /* while */ Expect (bnflex_FNBtok, stopset); } /* Main := Header Decls Footer Rules first symbols:codetok cannot reachend */ static void Main (pge_SetOfStop stopset) { Header (stopset|(pge_SetOfStop) ((1 << (bnflex_codetok-bnflex_identtok)))); Decls (stopset|(pge_SetOfStop) ((1 << (bnflex_codetok-bnflex_identtok)))); Footer (stopset|(pge_SetOfStop) ((1 << (bnflex_codetok-bnflex_identtok)))); Rules (stopset); } /* Header := '%' 'module' StartModName first symbols:codetok cannot reachend */ static void Header (pge_SetOfStop stopset) { Expect (bnflex_codetok, stopset|(pge_SetOfStop) ((1 << (bnflex_moduletok-bnflex_identtok)))); Expect (bnflex_moduletok, stopset|(pge_SetOfStop) ((1 << (bnflex_identtok-bnflex_identtok)))); StartModName (stopset); } /* Decls := '%' 'declaration' DoDeclaration first symbols:codetok cannot reachend */ static void Decls (pge_SetOfStop stopset) { Expect (bnflex_codetok, stopset|(pge_SetOfStop) ((1 << (bnflex_declarationtok-bnflex_identtok)))); Expect (bnflex_declarationtok, stopset|(pge_SetOfStop) ((1 << (bnflex_identtok-bnflex_identtok)))); DoDeclaration (stopset); } /* Footer := '%' 'module' EndModName first symbols:codetok cannot reachend */ static void Footer (pge_SetOfStop stopset) { Expect (bnflex_codetok, stopset|(pge_SetOfStop) ((1 << (bnflex_moduletok-bnflex_identtok)))); Expect (bnflex_moduletok, stopset|(pge_SetOfStop) ((1 << (bnflex_identtok-bnflex_identtok)))); EndModName (stopset); } /* First := 'first' '{' { LitOrTokenOrIdent % WITH CurrentSetDesc^ DO next := TailProduction^.first ; END ; TailProduction^.first := CurrentSetDesc % } '}' first symbols:firsttok cannot reachend */ static void First (pge_SetOfStop stopset) { Expect (bnflex_firsttok, stopset|(pge_SetOfStop) ((1 << (bnflex_lcparatok-bnflex_identtok)))); 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)))); while ((((1 << (bnflex_GetCurrentTokenType ())) & ((unsigned int) ((1 << (bnflex_lesstok)) | (1 << (bnflex_identtok)) | (1 << (bnflex_squotetok)) | (1 << (bnflex_dquotetok))))) != 0)) { 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)))); CurrentSetDesc->next = TailProduction->first; TailProduction->first = CurrentSetDesc; } /* while */ Expect (bnflex_rcparatok, stopset); } /* Follow := 'follow' '{' { LitOrTokenOrIdent % WITH CurrentSetDesc^ DO next := TailProduction^.followinfo^.follow ; END ; TailProduction^.followinfo^.follow := CurrentSetDesc % } '}' first symbols:followtok cannot reachend */ static void Follow (pge_SetOfStop stopset) { Expect (bnflex_followtok, stopset|(pge_SetOfStop) ((1 << (bnflex_lcparatok-bnflex_identtok)))); 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)))); while ((((1 << (bnflex_GetCurrentTokenType ())) & ((unsigned int) ((1 << (bnflex_lesstok)) | (1 << (bnflex_identtok)) | (1 << (bnflex_squotetok)) | (1 << (bnflex_dquotetok))))) != 0)) { 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)))); CurrentSetDesc->next = TailProduction->followinfo->follow; TailProduction->followinfo->follow = CurrentSetDesc; } /* while */ Expect (bnflex_rcparatok, stopset); } /* LitOrTokenOrIdent := Literal % CurrentSetDesc := NewSetDesc() ; WITH CurrentSetDesc^ DO type := litel ; string := LastLiteral ; END ; % | '<' CollectTok '>' | Ident % CurrentSetDesc := NewSetDesc() ; WITH CurrentSetDesc^ DO type := idel ; ident := CurrentIdent ; END ; % first symbols:dquotetok, squotetok, identtok, lesstok cannot reachend */ static void LitOrTokenOrIdent (pge_SetOfStop stopset) { if ((((1 << (bnflex_GetCurrentTokenType ())) & ((unsigned int) ((1 << (bnflex_dquotetok)) | (1 << (bnflex_squotetok))))) != 0)) { Literal (stopset); CurrentSetDesc = NewSetDesc (); CurrentSetDesc->type = pge_litel; CurrentSetDesc->string = LastLiteral; } else if ((bnflex_GetCurrentTokenType ()) == bnflex_lesstok) { /* avoid dangling else. */ Expect (bnflex_lesstok, stopset|(pge_SetOfStop) ((1 << (bnflex_identtok-bnflex_identtok)))); CollectTok (stopset|(pge_SetOfStop) ((1 << (bnflex_gretok-bnflex_identtok)))); Expect (bnflex_gretok, stopset); } else if ((bnflex_GetCurrentTokenType ()) == bnflex_identtok) { /* avoid dangling else. */ Ident (stopset); CurrentSetDesc = NewSetDesc (); CurrentSetDesc->type = pge_idel; CurrentSetDesc->ident = CurrentIdent; } else { /* avoid dangling else. */ PushBackInput_WarnError ((const char *) "expecting one of: identifier < \" single quote", 45); } } /* Literal := '"' CollectLiteral '"' | "'" CollectLiteral "'" first symbols:squotetok, dquotetok cannot reachend */ static void Literal (pge_SetOfStop stopset) { if ((bnflex_GetCurrentTokenType ()) == bnflex_dquotetok) { Expect (bnflex_dquotetok, stopset|(pge_SetOfStop) ((1 << (bnflex_literaltok-bnflex_identtok)))); CollectLiteral (stopset|(pge_SetOfStop) ((1 << (bnflex_dquotetok-bnflex_identtok)))); Expect (bnflex_dquotetok, stopset); } else if ((bnflex_GetCurrentTokenType ()) == bnflex_squotetok) { /* avoid dangling else. */ Expect (bnflex_squotetok, stopset|(pge_SetOfStop) ((1 << (bnflex_literaltok-bnflex_identtok)))); CollectLiteral (stopset|(pge_SetOfStop) ((1 << (bnflex_squotetok-bnflex_identtok)))); Expect (bnflex_squotetok, stopset); } else { /* avoid dangling else. */ PushBackInput_WarnError ((const char *) "expecting one of: single quote \"", 32); } } /* Token := Literal DefineToken first symbols:dquotetok, squotetok cannot reachend */ static void Token (pge_SetOfStop stopset) { Literal (stopset|(pge_SetOfStop) ((1 << (bnflex_identtok-bnflex_identtok)))); DefineToken (stopset); } /* ErrorProcedures := Literal % ErrorProcArray := LastLiteral % Literal % ErrorProcString := LastLiteral % first symbols:dquotetok, squotetok cannot reachend */ static void ErrorProcedures (pge_SetOfStop stopset) { Literal (stopset|(pge_SetOfStop) ((1 << (bnflex_squotetok-bnflex_identtok)) | (1 << (bnflex_dquotetok-bnflex_identtok)))); ErrorProcArray = LastLiteral; Literal (stopset); ErrorProcString = LastLiteral; } /* TokenProcedure := Literal % TokenTypeProc := LastLiteral % first symbols:dquotetok, squotetok cannot reachend */ static void TokenProcedure (pge_SetOfStop stopset) { Literal (stopset); TokenTypeProc = LastLiteral; } /* SymProcedure := Literal % SymIsProc := LastLiteral % first symbols:dquotetok, squotetok cannot reachend */ static void SymProcedure (pge_SetOfStop stopset) { Literal (stopset); SymIsProc = LastLiteral; } /* Production := Statement first symbols:identtok cannot reachend */ static void Production (pge_SetOfStop stopset) { Statement (stopset); } /* Expression := % VAR t1, t2: TermDesc ; e : ExpressionDesc ; % % e := CurrentExpression ; t1 := NewTerm() ; CurrentTerm := t1 ; % Term % e^.term := t1 ; % { '|' % t2 := NewTerm() ; CurrentTerm := t2 % Term % t1^.next := t2 ; t1 := t2 % } first symbols:dquotetok, squotetok, lparatok, lsparatok, lcparatok, identtok, codetok cannot reachend */ static void Expression (pge_SetOfStop stopset) { pge_TermDesc t1; pge_TermDesc t2; pge_ExpressionDesc e; e = CurrentExpression; t1 = NewTerm (); CurrentTerm = t1; Term (stopset|(pge_SetOfStop) ((1 << (bnflex_bartok-bnflex_identtok)))); e->term = t1; while ((bnflex_GetCurrentTokenType ()) == bnflex_bartok) { 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)))); t2 = NewTerm (); CurrentTerm = t2; Term (stopset|(pge_SetOfStop) ((1 << (bnflex_bartok-bnflex_identtok)))); t1->next = t2; t1 = t2; } /* while */ } /* Term := % VAR t1: TermDesc ; f1, f2: FactorDesc ; % % CurrentFactor := NewFactor() ; f1 := CurrentFactor ; t1 := CurrentTerm ; % Factor % t1^.factor := f1 ; f2 := NewFactor() ; CurrentFactor := f2 % { Factor % f1^.next := f2 ; f1 := f2 ; f2 := NewFactor() ; CurrentFactor := f2 ; % } first symbols:squotetok, dquotetok, codetok, identtok, lcparatok, lsparatok, lparatok cannot reachend */ static void Term (pge_SetOfStop stopset) { pge_TermDesc t1; pge_FactorDesc f1; pge_FactorDesc f2; CurrentFactor = NewFactor (); f1 = CurrentFactor; t1 = CurrentTerm; 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)))); t1->factor = f1; f2 = NewFactor (); CurrentFactor = f2; 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)) { 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)))); f1->next = f2; f1 = f2; f2 = NewFactor (); CurrentFactor = f2; } /* while */ } /* GetDefinitionName - returns the name of the rule inside, p. */ static NameKey_Name GetDefinitionName (pge_ProductionDesc p) { if (p != NULL) { if ((p->statement != NULL) && (p->statement->ident != NULL)) { return p->statement->ident->name; } } return NameKey_NulName; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* FindDefinition - searches and returns the rule which defines, n. */ static pge_ProductionDesc FindDefinition (NameKey_Name n) { pge_ProductionDesc p; pge_ProductionDesc f; p = HeadProduction; f = NULL; while (p != NULL) { if ((GetDefinitionName (p)) == n) { /* avoid gcc warning by using compound statement even if not strictly necessary. */ if (f == NULL) { f = p; } else { StrIO_WriteString ((const char *) "multiple definition for rule: ", 30); NameKey_WriteKey (n); StrIO_WriteLn (); } } p = p->next; } return f; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* BackPatchIdent - found an ident, i, we must look for the corresponding rule and set the definition accordingly. */ static void BackPatchIdent (pge_IdentDesc i) { if (i != NULL) { i->definition = FindDefinition (i->name); if (i->definition == NULL) { WarnError1 ((const char *) "unable to find production %s", 28, i->name); WasNoError = false; } } } /* BackPatchFactor - runs through the factor looking for an ident */ static void BackPatchFactor (pge_FactorDesc f) { while (f != NULL) { switch (f->type) { case pge_id: BackPatchIdent (f->ident); break; case pge_sub: case pge_opt: case pge_mult: BackPatchExpression (f->expr); break; default: break; } f = f->next; } } /* BackPatchTerm - runs through all terms to find idents. */ static void BackPatchTerm (pge_TermDesc t) { while (t != NULL) { BackPatchFactor (t->factor); t = t->next; } } /* BackPatchExpression - runs through the term to find any idents. */ static void BackPatchExpression (pge_ExpressionDesc e) { if (e != NULL) { BackPatchTerm (e->term); } } /* BackPatchSet - */ static void BackPatchSet (pge_SetDesc s) { while (s != NULL) { switch (s->type) { case pge_idel: BackPatchIdent (s->ident); break; default: break; } s = s->next; } } /* BackPatchIdentToDefinitions - search through all the rules and add a link from any ident to the definition. */ static void BackPatchIdentToDefinitions (pge_ProductionDesc d) { if ((d != NULL) && (d->statement != NULL)) { BackPatchExpression (d->statement->expr); } } /* CalculateFirstAndFollow - */ static void CalculateFirstAndFollow (pge_ProductionDesc p) { if (Debugging) { StrIO_WriteLn (); NameKey_WriteKey (p->statement->ident->name); StrIO_WriteLn (); StrIO_WriteString ((const char *) " calculating first", 19); } CalcFirstProduction (p, p, &p->first); BackPatchSet (p->first); if (Debugging) { StrIO_WriteString ((const char *) " calculating follow set", 24); } if (p->followinfo->follow == NULL) { CalcFollowProduction (p); } BackPatchSet (p->followinfo->follow); } /* ForeachRuleDo - */ static void ForeachRuleDo (pge_DoProcedure p) { CurrentProduction = HeadProduction; while (CurrentProduction != NULL) { (*p.proc) (CurrentProduction); CurrentProduction = CurrentProduction->next; } } /* WhileNotCompleteDo - */ static void WhileNotCompleteDo (pge_DoProcedure p) { do { Finished = true; ForeachRuleDo (p); } while (! (Finished)); } /* NewLine - generate a newline and indent. */ static void NewLine (unsigned int Left) { Output_WriteLn (); BeginningOfLine = true; Indent = 0; while (Indent < Left) { Output_Write (' '); Indent += 1; } } /* CheckNewLine - */ static void CheckNewLine (unsigned int Left) { if (Indent == Left) { Left = BaseNewLine; } if (Indent > BaseRightMargin) { NewLine (Left); } } /* IndentString - writes out a string with a preceeding indent. */ static void IndentString (const char *a_, unsigned int _a_high) { unsigned int i; char a[_a_high+1]; /* make a local copy of each unbounded array. */ memcpy (a, a_, _a_high+1); i = 0; while (i < Indent) { Output_Write (' '); i += 1; } Output_WriteString ((const char *) a, _a_high); LastLineNo = 0; } /* KeyWord - writes out a keywork with optional formatting directives. */ static void KeyWord (NameKey_Name n) { if (KeywordFormatting) { Output_WriteString ((const char *) "{%K", 3); if (((n == (NameKey_MakeKey ((const char *) "}", 1))) || (n == (NameKey_MakeKey ((const char *) "{", 1)))) || (n == (NameKey_MakeKey ((const char *) "%", 1)))) { Output_Write ('%'); /* escape }, { or % */ } Output_WriteKey (n); Output_Write ('}'); } else { Output_WriteKey (n); } } /* PrettyPara - */ static void PrettyPara (const char *c1_, unsigned int _c1_high, const char *c2_, unsigned int _c2_high, pge_ExpressionDesc e, unsigned int Left) { char c1[_c1_high+1]; char c2[_c2_high+1]; /* make a local copy of each unbounded array. */ memcpy (c1, c1_, _c1_high+1); memcpy (c2, c2_, _c2_high+1); Output_WriteString ((const char *) c1, _c1_high); Indent += StrLib_StrLen ((const char *) c1, _c1_high); Left = Indent; PrettyCommentExpression (e, Left); Output_WriteString ((const char *) c2, _c2_high); Indent += StrLib_StrLen ((const char *) c2, _c2_high); } /* WriteKeyTexinfo - */ static void WriteKeyTexinfo (NameKey_Name s) { DynamicStrings_String ds; char ch; unsigned int i; unsigned int l; if (Texinfo) { ds = DynamicStrings_InitStringCharStar (NameKey_KeyToCharStar (s)); l = DynamicStrings_Length (ds); i = 0; while (i < l) { ch = DynamicStrings_char (ds, static_cast (i)); if ((ch == '{') || (ch == '}')) { Output_Write ('@'); } Output_Write (ch); i += 1; } } else { Output_WriteKey (s); } } /* PrettyCommentFactor - */ static void PrettyCommentFactor (pge_FactorDesc f, unsigned int Left) { unsigned int curpos; bool seentext; while (f != NULL) { CheckNewLine (Left); switch (f->type) { case pge_id: Output_WriteKey (f->ident->name); Output_WriteString ((const char *) " ", 1); Indent += (NameKey_LengthKey (f->ident->name))+1; break; case pge_lit: if ((NameKey_MakeKey ((const char *) "'", 1)) == f->string) { Output_Write ('"'); WriteKeyTexinfo (f->string); Output_WriteString ((const char *) "\" ", 2); } else { Output_Write ('\''); WriteKeyTexinfo (f->string); Output_WriteString ((const char *) "' ", 2); } Indent += (NameKey_LengthKey (f->string))+3; break; case pge_sub: PrettyPara ((const char *) "( ", 2, (const char *) " ) ", 3, f->expr, Left); break; case pge_opt: PrettyPara ((const char *) "[ ", 2, (const char *) " ] ", 3, f->expr, Left); break; case pge_mult: if (Texinfo) { PrettyPara ((const char *) "@{ ", 3, (const char *) " @} ", 4, f->expr, Left); } else { PrettyPara ((const char *) "{ ", 2, (const char *) " } ", 3, f->expr, Left); } break; case pge_m2: if (EmitCode) { NewLine (Left); Output_WriteString ((const char *) "% ", 2); seentext = false; curpos = 0; WriteCodeHunkListIndent (f->code->code, f->code->indent, &curpos, Left+2, &seentext); Output_WriteString ((const char *) " %", 2); NewLine (Left); } break; default: break; } PrettyFollow ((const char *) "", 3, f->followinfo); f = f->next; } } /* PeepTerm - returns the length of characters in term. */ static unsigned int PeepTerm (pge_TermDesc t) { unsigned int l; l = 0; while (t != NULL) { l += PeepFactor (t->factor); if (t->next != NULL) { l += 3; } t = t->next; } return l; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* PeepExpression - returns the length of the expression. */ static unsigned int PeepExpression (pge_ExpressionDesc e) { if (e == NULL) { return 0; } else { return PeepTerm (e->term); } /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* PeepFactor - returns the length of character in the factor */ static unsigned int PeepFactor (pge_FactorDesc f) { unsigned int l; l = 0; while (f != NULL) { switch (f->type) { case pge_id: l += (NameKey_LengthKey (f->ident->name))+1; break; case pge_lit: l += (NameKey_LengthKey (f->string))+3; break; case pge_opt: case pge_mult: case pge_sub: l += PeepExpression (f->expr); break; case pge_m2: break; default: break; } f = f->next; /* empty */ } return l; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* PrettyCommentTerm - */ static void PrettyCommentTerm (pge_TermDesc t, unsigned int Left) { while (t != NULL) { CheckNewLine (Left); PrettyCommentFactor (t->factor, Left); if (t->next != NULL) { Output_WriteString ((const char *) " | ", 3); Indent += 3; if (((PeepFactor (t->factor))+Indent) > BaseRightMargin) { NewLine (Left); } } PrettyFollow ((const char *) "", 3, t->followinfo); t = t->next; } } /* PrettyCommentExpression - */ static void PrettyCommentExpression (pge_ExpressionDesc e, unsigned int Left) { if (e != NULL) { PrettyCommentTerm (e->term, Left); PrettyFollow ((const char *) "", 3, e->followinfo); } } /* PrettyCommentStatement - */ static void PrettyCommentStatement (pge_StatementDesc s, unsigned int Left) { if (s != NULL) { PrettyCommentExpression (s->expr, Left); PrettyFollow ((const char *) "", 3, s->followinfo); } } /* PrettyCommentProduction - generates the comment for rule, p. */ static void PrettyCommentProduction (pge_ProductionDesc p) { pge_SetDesc to; if (p != NULL) { BeginningOfLine = true; Indent = 0; Output_WriteString ((const char *) "(*", 2); NewLine (3); Output_WriteKey (GetDefinitionName (p)); Output_WriteString ((const char *) " := ", 4); Indent += (NameKey_LengthKey (GetDefinitionName (p)))+4; PrettyCommentStatement (p->statement, Indent); NewLine (0); if (ErrorRecovery) { NewLine (3); Output_WriteString ((const char *) "first symbols:", 15); EmitSet (p->first, static_cast (0), static_cast (0)); NewLine (3); PrettyFollow ((const char *) "", 3, p->followinfo); NewLine (3); switch (GetReachEnd (p->followinfo)) { case pge_true: Output_WriteString ((const char *) "reachend", 8); break; case pge_false: Output_WriteString ((const char *) "cannot reachend", 15); break; case pge_unknown: Output_WriteString ((const char *) "unknown...", 10); break; default: break; } NewLine (0); } Output_WriteString ((const char *) "*)", 2); NewLine (0); } } /* PrettyPrintProduction - pretty prints the ebnf rule, p. */ static void PrettyPrintProduction (pge_ProductionDesc p) { pge_SetDesc to; if (p != NULL) { BeginningOfLine = true; Indent = 0; if (Texinfo) { Output_WriteString ((const char *) "@example", 8); NewLine (0); } else if (Sphinx) { /* avoid dangling else. */ Output_WriteString ((const char *) ".. code-block:: ebnf", 20); NewLine (0); } Output_WriteKey (GetDefinitionName (p)); Output_WriteString ((const char *) " := ", 4); Indent += (NameKey_LengthKey (GetDefinitionName (p)))+4; PrettyCommentStatement (p->statement, Indent); if (p->description != NameKey_NulName) { Output_WriteKey (p->description); } NewLine (0); WriteIndent ((NameKey_LengthKey (GetDefinitionName (p)))+1); Output_WriteString ((const char *) " =: ", 4); NewLine (0); if (Texinfo) { Output_WriteString ((const char *) "@findex ", 8); Output_WriteKey (GetDefinitionName (p)); Output_WriteString ((const char *) " (ebnf)", 7); NewLine (0); Output_WriteString ((const char *) "@end example", 12); NewLine (0); } else if (Sphinx) { /* avoid dangling else. */ Output_WriteString ((const char *) ".. index::", 10); NewLine (0); Output_WriteString ((const char *) " pair: ", 8); Output_WriteKey (GetDefinitionName (p)); Output_WriteString ((const char *) "; (ebnf)", 8); NewLine (0); } NewLine (0); } } /* EmitFileLineTag - emits a line and file tag using the C preprocessor syntax. */ static void EmitFileLineTag (unsigned int line) { if (! SuppressFileLineTag && (line != LastLineNo)) { LastLineNo = line; if (! OnLineStart) { Output_WriteLn (); } Output_WriteString ((const char *) "# ", 2); Output_WriteCard (line, 0); Output_WriteString ((const char *) " \"", 2); Output_WriteString ((const char *) &FileName.array[0], MaxFileName); Output_Write ('"'); Output_WriteLn (); OnLineStart = true; } } /* EmitRule - generates a comment and code for rule, p. */ static void EmitRule (pge_ProductionDesc p) { if (PrettyPrint) { PrettyPrintProduction (p); } else { PrettyCommentProduction (p); if (ErrorRecovery) { RecoverProduction (p); } else { CodeProduction (p); } } } /* CodeCondition - */ static void CodeCondition (pge_m2condition m) { switch (m) { case pge_m2if: case pge_m2none: IndentString ((const char *) "IF ", 3); break; case pge_m2elsif: IndentString ((const char *) "ELSIF ", 6); break; case pge_m2while: IndentString ((const char *) "WHILE ", 6); break; default: Debug_Halt ((const char *) "unrecognised m2condition", 24, (const char *) "m2/gm2-auto/pge.mod", 19, (const char *) "CodeCondition", 13, 2686); break; } } /* CodeThenDo - codes a "THEN" or "DO" depending upon, m. */ static void CodeThenDo (pge_m2condition m) { switch (m) { case pge_m2if: case pge_m2none: case pge_m2elsif: if (LastLineNo == 0) { Output_WriteLn (); } IndentString ((const char *) "THEN", 4); Output_WriteLn (); break; case pge_m2while: Output_WriteString ((const char *) " DO", 3); Output_WriteLn (); break; default: Debug_Halt ((const char *) "unrecognised m2condition", 24, (const char *) "m2/gm2-auto/pge.mod", 19, (const char *) "CodeThenDo", 10, 2712); break; } OnLineStart = true; } /* CodeElseEnd - builds an ELSE END statement using string, end. */ static void CodeElseEnd (const char *end_, unsigned int _end_high, bool consumed, pge_FactorDesc f, bool inopt) { char end[_end_high+1]; /* make a local copy of each unbounded array. */ memcpy (end, end_, _end_high+1); Output_WriteLn (); OnLineStart = true; EmitFileLineTag (f->line); if (! inopt) { IndentString ((const char *) "ELSE", 4); StrIO_WriteLn (); Indent += 3; if (consumed) { IndentString ((const char *) "", 0); Output_WriteKey (ErrorProcArray); Output_Write ('('); switch (f->type) { case pge_id: Output_Write ('\''); Output_WriteKey (f->ident->name); Output_WriteString ((const char *) " - expected", 11); Output_WriteString ((const char *) "') ;", 4); break; case pge_lit: if ((NameKey_MakeKey ((const char *) "'", 1)) == f->string) { Output_Write ('"'); KeyWord (f->string); Output_WriteString ((const char *) " - expected", 11); Output_WriteString ((const char *) "\") ;", 4); } else if ((NameKey_MakeKey ((const char *) "\"", 1)) == f->string) { /* avoid dangling else. */ Output_Write ('\''); KeyWord (f->string); Output_WriteString ((const char *) " - expected", 11); Output_WriteString ((const char *) "') ;", 4); } else { /* avoid dangling else. */ Output_Write ('"'); Output_Write ('\''); KeyWord (f->string); Output_WriteString ((const char *) "' - expected", 12); Output_WriteString ((const char *) "\") ;", 4); } break; default: break; } Output_WriteLn (); } IndentString ((const char *) "RETURN( FALSE )", 15); Indent -= 3; Output_WriteLn (); } IndentString ((const char *) end, _end_high); Output_WriteLn (); OnLineStart = true; } /* CodeEnd - codes a "END" depending upon, m. */ static void CodeEnd (pge_m2condition m, pge_TermDesc t, bool consumed, pge_FactorDesc f, bool inopt) { Indent -= 3; Output_WriteLn (); OnLineStart = true; switch (m) { case pge_m2none: if (t == NULL) { CodeElseEnd ((const char *) "END ;", 5, consumed, f, inopt); } break; case pge_m2if: if (t == NULL) { CodeElseEnd ((const char *) "END ; (* if *)", 15, consumed, f, inopt); } break; case pge_m2elsif: if (t == NULL) { CodeElseEnd ((const char *) "END ; (* elsif *)", 18, consumed, f, inopt); } break; case pge_m2while: IndentString ((const char *) "END ; (* while *)", 18); break; default: Debug_Halt ((const char *) "unrecognised m2condition", 24, (const char *) "m2/gm2-auto/pge.mod", 19, (const char *) "CodeEnd", 7, 2796); break; } OnLineStart = false; } /* EmitNonVarCode - writes out, code, providing it is not a variable declaration. */ static void EmitNonVarCode (pge_CodeDesc code, unsigned int curpos, unsigned int left) { unsigned int i; pge_CodeHunk t; bool seentext; t = code->code; if ((! (FindStr (&t, &i, (const char *) "VAR", 3))) && EmitCode) { seentext = false; curpos = 0; EmitFileLineTag (code->line); IndentString ((const char *) "", 0); WriteCodeHunkListIndent (code->code, code->indent, &curpos, left, &seentext); Output_WriteString ((const char *) " ;", 2); Output_WriteLn (); OnLineStart = true; } } /* ChainOn - */ static pge_FactorDesc ChainOn (pge_FactorDesc codeStack, pge_FactorDesc f) { pge_FactorDesc s; f->pushed = NULL; if (codeStack == NULL) { return f; } else { s = codeStack; while (s->pushed != NULL) { s = s->pushed; } s->pushed = f; return codeStack; } /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* FlushCode - */ static void FlushCode (pge_FactorDesc *codeStack) { if ((*codeStack) != NULL) { NewLine (Indent); Output_WriteString ((const char *) "(* begin flushing code *)", 25); OnLineStart = false; while ((*codeStack) != NULL) { NewLine (Indent); EmitNonVarCode ((*codeStack)->code, 0, Indent); NewLine (Indent); (*codeStack) = (*codeStack)->pushed; if ((*codeStack) != NULL) { Output_WriteString ((const char *) " (* again flushing code *)", 26); Output_WriteLn (); OnLineStart = true; } } NewLine (Indent); Output_WriteString ((const char *) "(* end flushing code *)", 23); OnLineStart = false; } } /* CodeFactor - */ static void CodeFactor (pge_FactorDesc f, pge_TermDesc t, pge_m2condition l, pge_m2condition n, bool inopt, bool inwhile, bool consumed, pge_FactorDesc codeStack) { if (f == NULL) { /* avoid dangling else. */ if (! inwhile && ! inopt) /* ((l=m2elsif) OR (l=m2if) OR (l=m2none)) AND */ { Output_WriteLn (); IndentString ((const char *) "RETURN( TRUE )", 14); OnLineStart = false; } } else { EmitFileLineTag (f->line); switch (f->type) { case pge_id: FlushCode (&codeStack); CodeCondition (n); Output_WriteKey (f->ident->name); Output_WriteString ((const char *) "()", 2); CodeThenDo (n); Indent += 3; CodeFactor (f->next, NULL, n, pge_m2none, inopt, inwhile, true, NULL); CodeEnd (n, t, consumed, f, inopt); break; case pge_lit: FlushCode (&codeStack); CodeCondition (n); Output_WriteKey (SymIsProc); Output_Write ('('); Output_WriteKey (SymbolKey_GetSymKey (Aliases, f->string)); Output_Write (')'); CodeThenDo (n); Indent += 3; CodeFactor (f->next, NULL, n, pge_m2none, inopt, inwhile, true, NULL); CodeEnd (n, t, consumed, f, inopt); break; case pge_sub: FlushCode (&codeStack); CodeExpression (f->expr, pge_m2none, inopt, inwhile, consumed, NULL); if (f->next != NULL) { /* * the test above makes sure that we don't emit a RETURN( TRUE ) * after a subexpression. Remember sub expressions are not conditional */ CodeFactor (f->next, t, n, pge_m2none, inopt, inwhile, true, NULL); } break; case pge_opt: FlushCode (&codeStack); CodeExpression (f->expr, pge_m2if, true, inwhile, false, NULL); CodeFactor (f->next, t, n, pge_m2none, inopt, inwhile, consumed, NULL); break; case pge_mult: FlushCode (&codeStack); CodeExpression (f->expr, pge_m2while, false, true, consumed, NULL); CodeFactor (f->next, t, n, pge_m2none, inopt, inwhile, consumed, NULL); break; case pge_m2: codeStack = ChainOn (codeStack, f); if (consumed || (f->next == NULL)) { FlushCode (&codeStack); } CodeFactor (f->next, t, n, pge_m2none, inopt, inwhile, consumed, codeStack); break; default: break; } } } /* CodeTerm - */ static void CodeTerm (pge_TermDesc t, pge_m2condition m, bool inopt, bool inwhile, bool consumed, pge_FactorDesc codeStack) { pge_m2condition l; l = m; while (t != NULL) { EmitFileLineTag (t->line); if ((t->factor->type == pge_m2) && (m == pge_m2elsif)) { m = pge_m2if; IndentString ((const char *) "ELSE", 4); Output_WriteLn (); OnLineStart = true; Indent += 3; CodeFactor (t->factor, t->next, pge_m2none, pge_m2none, inopt, inwhile, consumed, codeStack); Indent -= 3; IndentString ((const char *) "END ;", 5); Output_WriteLn (); OnLineStart = true; } else { CodeFactor (t->factor, t->next, pge_m2none, m, inopt, inwhile, consumed, codeStack); } l = m; if (t->next != NULL) { m = pge_m2elsif; } t = t->next; } } /* CodeExpression - */ static void CodeExpression (pge_ExpressionDesc e, pge_m2condition m, bool inopt, bool inwhile, bool consumed, pge_FactorDesc codeStack) { if (e != NULL) { EmitFileLineTag (e->line); CodeTerm (e->term, m, inopt, inwhile, consumed, codeStack); } } /* CodeStatement - */ static void CodeStatement (pge_StatementDesc s, pge_m2condition m) { if (s != NULL) { EmitFileLineTag (s->line); CodeExpression (s->expr, m, false, false, false, NULL); } } /* CodeProduction - only encode grammer rules which are not special. */ static void CodeProduction (pge_ProductionDesc p) { if ((p != NULL) && (! p->firstsolved || ((p->statement != NULL) && (p->statement->expr != NULL)))) { BeginningOfLine = true; Indent = 0; Output_WriteLn (); EmitFileLineTag (p->line); IndentString ((const char *) "PROCEDURE ", 10); Output_WriteKey (GetDefinitionName (p)); Output_WriteString ((const char *) " () : BOOLEAN ;", 15); VarProduction (p); Output_WriteLn (); OnLineStart = true; EmitFileLineTag (p->line); IndentString ((const char *) "BEGIN", 5); StrIO_WriteLn (); OnLineStart = false; EmitFileLineTag (p->line); Indent = 3; CodeStatement (p->statement, pge_m2none); Output_WriteLn (); Indent = 0; IndentString ((const char *) "END ", 4); NameKey_WriteKey (GetDefinitionName (p)); Output_WriteString ((const char *) " ;", 2); Output_WriteLn (); Output_WriteLn (); Output_WriteLn (); } } /* RecoverCondition - */ static void RecoverCondition (pge_m2condition m) { switch (m) { case pge_m2if: IndentString ((const char *) "IF ", 3); break; case pge_m2none: IndentString ((const char *) "IF ", 3); break; case pge_m2elsif: IndentString ((const char *) "ELSIF ", 6); break; case pge_m2while: IndentString ((const char *) "WHILE ", 6); break; default: Debug_Halt ((const char *) "unrecognised m2condition", 24, (const char *) "m2/gm2-auto/pge.mod", 19, (const char *) "RecoverCondition", 16, 3054); break; } } /* ConditionIndent - returns the number of spaces indentation created via, m. */ static unsigned int ConditionIndent (pge_m2condition m) { switch (m) { case pge_m2if: return 3; break; case pge_m2none: return 3; break; case pge_m2elsif: return 6; break; case pge_m2while: return 6; break; default: Debug_Halt ((const char *) "unrecognised m2condition", 24, (const char *) "m2/gm2-auto/pge.mod", 19, (const char *) "ConditionIndent", 15, 3074); break; } ReturnException ("m2/gm2-auto/pge.mod", 1, 7); __builtin_unreachable (); } /* WriteGetTokenType - writes out the method of determining the token type. */ static void WriteGetTokenType (void) { Output_WriteKey (TokenTypeProc); } /* NumberOfElements - returns the number of elements in set, to, which lie between low..high */ static unsigned int NumberOfElements (pge_SetDesc to, unsigned int low, unsigned int high) { unsigned int n; n = 0; while (to != NULL) { switch (to->type) { case pge_tokel: if ((high == 0) || (IsBetween (to->string, low, high))) { n += 1; } break; case pge_litel: if ((high == 0) || (IsBetween (SymbolKey_GetSymKey (Aliases, to->string), low, high))) { n += 1; } break; case pge_idel: PushBackInput_WarnError ((const char *) "not expecting ident in first symbol list", 40); WasNoError = false; break; default: PushBackInput_WarnError ((const char *) "unknown enuneration element", 27); WasNoError = false; break; } to = to->next; } return n; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* WriteElement - writes the literal name for element, e. */ static void WriteElement (unsigned int e) { Output_WriteKey (SymbolKey_GetSymKey (ReverseValues, e)); } /* EmitIsInSet - writes out the equivalent of GetTokenType() IN { toset } */ static void EmitIsInSet (pge_SetDesc to, NameKey_Name low, NameKey_Name high) { if ((NumberOfElements (to, low, high)) == 1) { WriteGetTokenType (); Output_Write ('='); EmitSet (to, low, high); } else { WriteGetTokenType (); Output_WriteString ((const char *) " IN SetOfStop", 13); if (LargestValue > MaxElementsInSet) { Output_WriteCard (((unsigned int ) (low)) / MaxElementsInSet, 0); } Output_WriteString ((const char *) " {", 2); EmitSet (to, low, high); Output_WriteString ((const char *) "}", 1); } } /* EmitIsInSubSet - writes out a test to see whether GetTokenype() is in { subset } */ static void EmitIsInSubSet (pge_SetDesc to, unsigned int low, unsigned int high) { if ((NumberOfElements (to, low, high)) == 1) { Output_Write ('('); EmitIsInSet (to, low, high); Output_Write (')'); } else if (low == 0) { /* avoid dangling else. */ /* no need to check whether GetTokenType > low */ Output_WriteString ((const char *) "((", 2); WriteGetTokenType (); Output_Write ('<'); WriteElement (static_cast (((int ) (high))+1)); Output_WriteString ((const char *) ") AND (", 7); EmitIsInSet (to, low, high); Output_WriteString ((const char *) "))", 2); } else if (((unsigned int ) (high)) > LargestValue) { /* avoid dangling else. */ /* no need to check whether GetTokenType < high */ Output_WriteString ((const char *) "((", 2); WriteGetTokenType (); Output_WriteString ((const char *) ">=", 2); WriteElement (low); Output_WriteString ((const char *) ") AND (", 7); EmitIsInSet (to, low, high); Output_WriteString ((const char *) "))", 2); } else { /* avoid dangling else. */ Output_WriteString ((const char *) "((", 2); WriteGetTokenType (); Output_WriteString ((const char *) ">=", 2); WriteElement (low); Output_WriteString ((const char *) ") AND (", 7); WriteGetTokenType (); Output_Write ('<'); WriteElement (static_cast (((int ) (high))+1)); Output_WriteString ((const char *) ") AND (", 7); EmitIsInSet (to, low, high); Output_WriteString ((const char *) "))", 2); } } /* EmitIsInFirst - */ static void EmitIsInFirst (pge_SetDesc to, pge_m2condition m) { unsigned int i; bool first; if ((NumberOfElements (to, static_cast (0), static_cast (0))) == 1) { /* only one element */ WriteGetTokenType (); Output_Write ('='); EmitSet (to, static_cast (0), static_cast (0)); } else { if (LargestValue <= MaxElementsInSet) { Output_Write ('('); WriteGetTokenType (); Output_WriteString ((const char *) " IN ", 4); EmitSetAsParameters (to); Output_WriteString ((const char *) ")", 1); } else { i = 0; first = true; do { if (! (IsEmptySet (to, i*MaxElementsInSet, ((i+1)*MaxElementsInSet)-1))) { if (! first) { Output_WriteString ((const char *) " OR", 3); NewLine (Indent+(ConditionIndent (m))); Indent -= ConditionIndent (m); } EmitIsInSubSet (to, i*MaxElementsInSet, ((i+1)*MaxElementsInSet)-1); first = false; } i += 1; } while (! ((i*MaxElementsInSet) > LargestValue)); } } } static void FlushRecoverCode (pge_FactorDesc *codeStack) { /* FlushCode - */ if ((*codeStack) != NULL) { while ((*codeStack) != NULL) { EmitNonVarCode ((*codeStack)->code, 0, Indent); (*codeStack) = (*codeStack)->pushed; } } } /* RecoverFactor - */ static void RecoverFactor (pge_FactorDesc f, pge_m2condition m, pge_FactorDesc codeStack) { pge_SetDesc to; if (f == NULL) {} /* empty. */ else { EmitFileLineTag (f->line); switch (f->type) { case pge_id: to = NULL; CalcFirstFactor (f, NULL, &to); if ((to != NULL) && (m != pge_m2none)) { RecoverCondition (m); EmitIsInFirst (to, m); CodeThenDo (m); Indent += 3; } FlushRecoverCode (&codeStack); IndentString ((const char *) "", 0); Output_WriteKey (f->ident->name); Output_Write ('('); EmitStopParametersAndFollow (f, m); Output_WriteString ((const char *) ") ;", 3); Output_WriteLn (); RecoverFactor (f->next, pge_m2none, codeStack); if ((to != NULL) && (m != pge_m2none)) { Indent -= 3; } break; case pge_lit: if (m == pge_m2none) { FlushRecoverCode (&codeStack); IndentString ((const char *) "Expect(", 7); Output_WriteKey (SymbolKey_GetSymKey (Aliases, f->string)); Output_WriteString ((const char *) ", ", 2); EmitStopParametersAndFollow (f, m); Output_WriteString ((const char *) ") ;", 3); Output_WriteLn (); RecoverFactor (f->next, pge_m2none, codeStack); } else { RecoverCondition (m); WriteGetTokenType (); Output_Write ('='); Output_WriteKey (SymbolKey_GetSymKey (Aliases, f->string)); CodeThenDo (m); Indent += 3; IndentString ((const char *) "Expect(", 7); Output_WriteKey (SymbolKey_GetSymKey (Aliases, f->string)); Output_WriteString ((const char *) ", ", 2); EmitStopParametersAndFollow (f, m); Output_WriteString ((const char *) ") ;", 3); Output_WriteLn (); FlushRecoverCode (&codeStack); RecoverFactor (f->next, pge_m2none, codeStack); Indent -= 3; } break; case pge_sub: FlushRecoverCode (&codeStack); RecoverExpression (f->expr, pge_m2none, m); RecoverFactor (f->next, pge_m2none, codeStack); break; case pge_opt: FlushRecoverCode (&codeStack); if (OptExpSeen (f)) { to = NULL; CalcFirstExpression (f->expr, NULL, &to); RecoverCondition (m); EmitIsInFirst (to, m); CodeThenDo (m); Indent += 3; IndentString ((const char *) "(* seen optional [ | ] expression *)", 36); Output_WriteLn (); stop (); RecoverExpression (f->expr, pge_m2none, pge_m2if); IndentString ((const char *) "(* end of optional [ | ] expression *)", 38); Output_WriteLn (); Indent -= 3; IndentString ((const char *) "END ;", 5); Output_WriteLn (); } else { RecoverExpression (f->expr, pge_m2if, m); } RecoverFactor (f->next, pge_m2none, codeStack); break; case pge_mult: FlushRecoverCode (&codeStack); if (((OptExpSeen (f)) || (m == pge_m2if)) || (m == pge_m2elsif)) { /* avoid dangling else. */ to = NULL; CalcFirstExpression (f->expr, NULL, &to); RecoverCondition (m); EmitIsInFirst (to, m); CodeThenDo (m); Indent += 3; IndentString ((const char *) "(* seen optional { | } expression *)", 36); Output_WriteLn (); RecoverCondition (pge_m2while); EmitIsInFirst (to, pge_m2while); CodeThenDo (pge_m2while); Indent += 3; RecoverExpression (f->expr, pge_m2none, pge_m2while); IndentString ((const char *) "(* end of optional { | } expression *)", 38); Output_WriteLn (); Indent -= 3; IndentString ((const char *) "END ;", 5); Output_WriteLn (); Indent -= 3; if (m == pge_m2none) { IndentString ((const char *) "END ;", 5); Output_WriteLn (); Indent -= 3; } } else { RecoverExpression (f->expr, pge_m2while, m); } RecoverFactor (f->next, pge_m2none, codeStack); break; case pge_m2: codeStack = ChainOn (codeStack, f); if (f->next == NULL) { FlushRecoverCode (&codeStack); } else { RecoverFactor (f->next, m, codeStack); /* was m2none */ } break; default: break; } } } /* OptExpSeen - returns TRUE if we can see an optional expression in the factor. This is not the same as epsilon. Example { '+' } matches epsilon as well as { '+' | '-' } but OptExpSeen returns TRUE in the second case and FALSE in the first. */ static bool OptExpSeen (pge_FactorDesc f) { if (f == NULL) { return false; } else { switch (f->type) { case pge_id: case pge_lit: return false; break; case pge_sub: return false; /* is this correct? */ break; case pge_opt: case pge_mult: return ((f->expr != NULL) && (f->expr->term != NULL)) && (f->expr->term->next != NULL); /* is this correct? */ break; case pge_m2: return true; break; default: break; } } PushBackInput_WarnError ((const char *) "all cases were not handled", 26); WasNoError = false; ReturnException ("m2/gm2-auto/pge.mod", 1, 7); __builtin_unreachable (); } /* RecoverTerm - */ static void RecoverTerm (pge_TermDesc t, pge_m2condition new_, pge_m2condition old) { bool LastWasM2Only; bool alternative; pge_SetDesc to; LastWasM2Only = (t->factor->type == pge_m2) && (t->factor->next == NULL); /* does the factor only contain inline code? */ to = NULL; CalcFirstTerm (t, NULL, &to); alternative = false; if (t->next != NULL) { new_ = pge_m2if; } while (t != NULL) { EmitFileLineTag (t->line); LastWasM2Only = (t->factor->type == pge_m2) && (t->factor->next == NULL); if ((t->factor->type == pge_m2) && (new_ == pge_m2elsif)) { new_ = pge_m2if; IndentString ((const char *) "ELSE", 4); Output_WriteLn (); Indent += 3; RecoverFactor (t->factor, pge_m2none, NULL); alternative = false; } else { RecoverFactor (t->factor, new_, NULL); } if (t->next != NULL) { new_ = pge_m2elsif; alternative = true; } t = t->next; } if ((new_ == pge_m2if) || (new_ == pge_m2elsif)) { if (alternative && (old != pge_m2while)) { IndentString ((const char *) "ELSE", 4); Output_WriteLn (); Indent += 3; IndentString ((const char *) "", 0); Output_WriteKey (ErrorProcArray); Output_WriteString ((const char *) "('expecting one of: ", 20); EmitSetName (to, static_cast (0), static_cast (0)); Output_WriteString ((const char *) "')", 2); Output_WriteLn (); Indent -= 3; } else if (LastWasM2Only) { /* avoid dangling else. */ Indent -= 3; } IndentString ((const char *) "END ;", 5); Output_WriteLn (); } else if (new_ == pge_m2while) { /* avoid dangling else. */ IndentString ((const char *) "END (* while *) ;", 17); Output_WriteLn (); } else if (LastWasM2Only) { /* avoid dangling else. */ Indent -= 3; } } /* RecoverExpression - */ static void RecoverExpression (pge_ExpressionDesc e, pge_m2condition new_, pge_m2condition old) { if (e != NULL) { EmitFileLineTag (e->line); RecoverTerm (e->term, new_, old); } } /* RecoverStatement - */ static void RecoverStatement (pge_StatementDesc s, pge_m2condition m) { if (s != NULL) { EmitFileLineTag (s->line); RecoverExpression (s->expr, m, pge_m2none); } } /* EmitFirstFactor - generate a list of all first tokens between the range: low..high. */ static void EmitFirstFactor (pge_FactorDesc f, unsigned int low, unsigned int high) { } /* EmitUsed - */ static void EmitUsed (unsigned int wordno) { if (! ((((1 << (wordno)) & (ParametersUsed)) != 0))) { Output_WriteString ((const char *) " (* <* unused *> *) ", 20); } } /* EmitStopParameters - generate the stop set. */ static void EmitStopParameters (bool FormalParameters) { unsigned int i; if (LargestValue <= MaxElementsInSet) { Output_WriteString ((const char *) "stopset", 7); if (FormalParameters) { Output_WriteString ((const char *) ": SetOfStop", 11); EmitUsed (0); } else { ParametersUsed |= (1 << (0 )); } } else { i = 0; do { Output_WriteString ((const char *) "stopset", 7); Output_WriteCard (i, 0); if (FormalParameters) { Output_WriteString ((const char *) ": SetOfStop", 11); Output_WriteCard (i, 0); EmitUsed (i); } else { ParametersUsed |= (1 << (i )); } i += 1; if ((i*MaxElementsInSet) < LargestValue) { /* avoid gcc warning by using compound statement even if not strictly necessary. */ if (FormalParameters) { Output_WriteString ((const char *) "; ", 2); } else { Output_WriteString ((const char *) ", ", 2); } } } while (! ((i*MaxElementsInSet) >= LargestValue)); } } /* IsBetween - returns TRUE if the value of the token, string, is in the range: low..high */ static bool IsBetween (NameKey_Name string, unsigned int low, unsigned int high) { return ((SymbolKey_GetSymKey (Values, string)) >= low) && ((SymbolKey_GetSymKey (Values, string)) <= high); /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* IsEmptySet - returns TRUE if no elements exist in set, to, with values, low..high. */ static bool IsEmptySet (pge_SetDesc to, unsigned int low, unsigned int high) { while (to != NULL) { switch (to->type) { case pge_tokel: if (IsBetween (to->string, low, high)) { return false; } break; case pge_litel: if (IsBetween (SymbolKey_GetSymKey (Aliases, to->string), low, high)) { return false; } break; case pge_idel: PushBackInput_WarnError ((const char *) "not expecting ident in first symbol list", 40); WasNoError = false; break; default: PushBackInput_WarnError ((const char *) "unknown enuneration element", 27); WasNoError = false; break; } to = to->next; } return true; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* EmitSet - emits the tokens in the set, to, which have values low..high */ static void EmitSet (pge_SetDesc to, unsigned int low, unsigned int high) { bool first; first = true; while (to != NULL) { switch (to->type) { case pge_tokel: if ((high == 0) || (IsBetween (to->string, low, high))) { if (! first) { Output_WriteString ((const char *) ", ", 2); } Output_WriteKey (to->string); first = false; } break; case pge_litel: if ((high == 0) || (IsBetween (SymbolKey_GetSymKey (Aliases, to->string), low, high))) { if (! first) { Output_WriteString ((const char *) ", ", 2); } Output_WriteKey (SymbolKey_GetSymKey (Aliases, to->string)); first = false; } break; case pge_idel: PushBackInput_WarnError ((const char *) "not expecting ident in first symbol list", 40); WasNoError = false; break; default: PushBackInput_WarnError ((const char *) "unknown enuneration element", 27); WasNoError = false; break; } to = to->next; } } /* EmitSetName - emits the tokens in the set, to, which have values low..high, using their names. */ static void EmitSetName (pge_SetDesc to, unsigned int low, unsigned int high) { while (to != NULL) { switch (to->type) { case pge_tokel: if ((high == 0) || (IsBetween (to->string, low, high))) { /* avoid gcc warning by using compound statement even if not strictly necessary. */ if ((NameKey_MakeKey ((const char *) "'", 1)) == (SymbolKey_GetSymKey (ReverseAliases, to->string))) { Output_WriteString ((const char *) "single quote", 12); } else { KeyWord (SymbolKey_GetSymKey (ReverseAliases, to->string)); } } break; case pge_litel: if ((high == 0) || (IsBetween (SymbolKey_GetSymKey (Aliases, to->string), low, high))) { Output_WriteKey (to->string); } break; case pge_idel: PushBackInput_WarnError ((const char *) "not expecting ident in first symbol list", 40); WasNoError = false; break; default: PushBackInput_WarnError ((const char *) "unknown enuneration element", 27); WasNoError = false; break; } to = to->next; if (to != NULL) { Output_Write (' '); } } } /* EmitStopParametersAndSet - generates the stop parameters together with a set inclusion of all the symbols in set, to. */ static void EmitStopParametersAndSet (pge_SetDesc to) { unsigned int i; if (LargestValue <= MaxElementsInSet) { /* avoid dangling else. */ Output_WriteString ((const char *) "stopset", 7); ParametersUsed |= (1 << (0 )); if ((to != NULL) && ((NumberOfElements (to, static_cast (0), static_cast (MaxElementsInSet-1))) > 0)) { Output_WriteString ((const char *) " + SetOfStop", 12); Output_Write ('{'); EmitSet (to, static_cast (0), static_cast (MaxElementsInSet-1)); Output_Write ('}'); } } else { i = 0; do { Output_WriteString ((const char *) "stopset", 7); Output_WriteCard (i, 0); ParametersUsed |= (1 << (i )); if ((to != NULL) && ((NumberOfElements (to, i*MaxElementsInSet, ((i+1)*MaxElementsInSet)-1)) > 0)) { Output_WriteString ((const char *) " + SetOfStop", 12); Output_WriteCard (i, 0); Output_Write ('{'); EmitSet (to, i*MaxElementsInSet, ((i+1)*MaxElementsInSet)-1); Output_Write ('}'); } i += 1; if ((i*MaxElementsInSet) < LargestValue) { Output_WriteString ((const char *) ", ", 2); } } while (! ((i*MaxElementsInSet) >= LargestValue)); } } /* EmitSetAsParameters - generates the first symbols as parameters to a set function. */ static void EmitSetAsParameters (pge_SetDesc to) { unsigned int i; if (LargestValue <= MaxElementsInSet) { Output_Write ('{'); EmitSet (to, static_cast (0), static_cast (MaxElementsInSet-1)); } else { i = 0; do { Output_Write ('{'); EmitSet (to, i*MaxElementsInSet, ((i+1)*MaxElementsInSet)-1); i += 1; if (((i+1)*MaxElementsInSet) > LargestValue) { Output_WriteString ((const char *) "}, ", 3); } } while (! (((i+1)*MaxElementsInSet) >= LargestValue)); } Output_Write ('}'); } /* EmitStopParametersAndFollow - generates the stop parameters together with a set inclusion of all the follow symbols for subsequent sentances. */ static void EmitStopParametersAndFollow (pge_FactorDesc f, pge_m2condition m) { pge_SetDesc to; to = NULL; /* IF m=m2while THEN CalcFirstFactor(f, NIL, to) END ; */ CollectFollow (&to, f->followinfo); EmitStopParametersAndSet (to); if (Debugging) { Output_WriteLn (); Output_WriteString ((const char *) "factor is: ", 11); PrettyCommentFactor (f, StrLib_StrLen ((const char *) "factor is: ", 11)); Output_WriteLn (); Output_WriteString ((const char *) "follow set:", 11); EmitSet (to, static_cast (0), static_cast (0)); Output_WriteLn (); } } /* EmitFirstAsParameters - */ static void EmitFirstAsParameters (pge_FactorDesc f) { pge_SetDesc to; to = NULL; CalcFirstFactor (f, NULL, &to); EmitSetAsParameters (to); } /* RecoverProduction - only encode grammer rules which are not special. Generate error recovery code. */ static void RecoverProduction (pge_ProductionDesc p) { DynamicStrings_String s; if ((p != NULL) && (! p->firstsolved || ((p->statement != NULL) && (p->statement->expr != NULL)))) { BeginningOfLine = true; Indent = 0; Output_WriteLn (); OnLineStart = false; EmitFileLineTag (p->line); IndentString ((const char *) "PROCEDURE ", 10); Output_WriteKey (GetDefinitionName (p)); Output_WriteString ((const char *) " (", 2); ParametersUsed = (unsigned int) 0; Output_StartBuffer (); Output_WriteString ((const char *) ") ;", 3); VarProduction (p); Output_WriteLn (); OnLineStart = false; EmitFileLineTag (p->line); Indent = 0; IndentString ((const char *) "BEGIN", 5); Output_WriteLn (); OnLineStart = false; EmitFileLineTag (p->line); Indent = 3; RecoverStatement (p->statement, pge_m2none); Indent = 0; IndentString ((const char *) "END ", 4); Output_WriteKey (GetDefinitionName (p)); Output_WriteString ((const char *) " ;", 2); Output_WriteLn (); Output_WriteLn (); Output_WriteLn (); s = Output_EndBuffer (); EmitStopParameters (true); Output_KillWriteS (s); } } /* IsWhite - returns TRUE if, ch, is a space or a tab. */ static bool IsWhite (char ch) { return ((ch == ' ') || (ch == ASCII_tab)) || (ch == ASCII_lf); /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* FindStr - returns TRUE if, str, was seen inside the code hunk */ static bool FindStr (pge_CodeHunk *code, unsigned int *i, const char *str_, unsigned int _str_high) { unsigned int j; unsigned int k; pge_CodeHunk t; char str[_str_high+1]; /* make a local copy of each unbounded array. */ memcpy (str, str_, _str_high+1); t = (*code); k = (StrLib_StrLen ((const char *) &(*code)->codetext.array[0], MaxCodeHunkLength))+1; while (t != NULL) { do { while ((k > 0) && (IsWhite (t->codetext.array[k-1]))) { k -= 1; } if (k == 0) { t = t->next; k = MaxCodeHunkLength+1; } } while (! ((t == NULL) || (! (IsWhite (t->codetext.array[k-1]))))); /* found another word check it */ if (t != NULL) { j = StrLib_StrLen ((const char *) str, _str_high); (*i) = k; while (((t != NULL) && (j > 0)) && ((str[j-1] == t->codetext.array[k-1]) || ((IsWhite (str[j-1])) && (IsWhite (t->codetext.array[k-1]))))) { j -= 1; k -= 1; if (j == 0) { /* found word remember position */ (*code) = t; } if (k == 0) { t = t->next; k = MaxCodeHunkLength+1; } } if (k > 0) { k -= 1; } else { t = t->next; } } } return (t == NULL) && (j == 0); /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* WriteUpto - */ static void WriteUpto (pge_CodeHunk code, pge_CodeHunk upto, unsigned int limit) { if (code != upto) { WriteUpto (code->next, upto, limit); Output_WriteString ((const char *) &code->codetext.array[0], MaxCodeHunkLength); } else { while ((limit <= MaxCodeHunkLength) && (code->codetext.array[limit] != ASCII_nul)) { Output_Write (code->codetext.array[limit]); limit += 1; } } } /* CheckForVar - checks for any local variables which need to be emitted during this production. */ static void CheckForVar (pge_CodeHunk code) { unsigned int i; pge_CodeHunk t; t = code; if ((FindStr (&t, &i, (const char *) "VAR", 3)) && EmitCode) { if (! EmittedVar) { Output_WriteLn (); Indent = 0; IndentString ((const char *) "VAR", 3); Indent += 3; Output_WriteLn (); EmittedVar = true; } WriteUpto (code, t, i); } } /* VarFactor - */ static void VarFactor (pge_FactorDesc f) { while (f != NULL) { switch (f->type) { case pge_id: break; case pge_lit: break; case pge_sub: case pge_opt: case pge_mult: VarExpression (f->expr); break; case pge_m2: CheckForVar (f->code->code); break; default: break; } f = f->next; } } /* VarTerm - */ static void VarTerm (pge_TermDesc t) { while (t != NULL) { VarFactor (t->factor); t = t->next; } } /* VarExpression - */ static void VarExpression (pge_ExpressionDesc e) { if (e != NULL) { VarTerm (e->term); } } /* VarStatement - */ static void VarStatement (pge_StatementDesc s) { if (s != NULL) { VarExpression (s->expr); } } /* VarProduction - writes out all variable declarations. */ static void VarProduction (pge_ProductionDesc p) { EmittedVar = false; if (p != NULL) { VarStatement (p->statement); } } /* In - returns TRUE if token, s, is already in the set, to. */ static bool In (pge_SetDesc to, NameKey_Name s) { while (to != NULL) { switch (to->type) { case pge_idel: if (s == to->ident->name) { return true; } break; case pge_tokel: case pge_litel: if (s == to->string) { return true; } break; default: PushBackInput_WarnError ((const char *) "internal error CASE type not known", 34); WasNoError = false; break; } to = to->next; } return false; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* IntersectionIsNil - given two set lists, s1, s2, return TRUE if the s1 * s2 = {} */ static bool IntersectionIsNil (pge_SetDesc s1, pge_SetDesc s2) { while (s1 != NULL) { switch (s1->type) { case pge_idel: if (In (s2, s1->ident->name)) { return false; } break; case pge_tokel: case pge_litel: if (In (s2, s1->string)) { return false; } break; default: PushBackInput_WarnError ((const char *) "internal error CASE type not known", 34); WasNoError = false; break; } s1 = s1->next; } return true; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* AddSet - adds a first symbol to a production. */ static void AddSet (pge_SetDesc *to, NameKey_Name s) { pge_SetDesc d; if (! (In ((*to), s))) { d = NewSetDesc (); d->type = pge_tokel; d->string = s; d->next = (*to); (*to) = d; Finished = false; } } /* OrSet - */ static void OrSet (pge_SetDesc *to, pge_SetDesc from) { while (from != NULL) { switch (from->type) { case pge_tokel: AddSet (to, from->string); break; case pge_litel: AddSet (to, SymbolKey_GetSymKey (Aliases, from->string)); break; case pge_idel: PushBackInput_WarnError ((const char *) "not expecting ident in first symbol list", 40); WasNoError = false; break; default: Debug_Halt ((const char *) "unknown element in enumeration type", 35, (const char *) "m2/gm2-auto/pge.mod", 19, (const char *) "OrSet", 5, 4133); break; } from = from->next; } } /* CalcFirstFactor - */ static void CalcFirstFactor (pge_FactorDesc f, pge_ProductionDesc from, pge_SetDesc *to) { while (f != NULL) { switch (f->type) { case pge_id: if (f->ident->definition == NULL) { WarnError1 ((const char *) "no rule found for an 'ident' called '%s'", 40, f->ident->name); M2RTS_HALT (-1); __builtin_unreachable (); } OrSet (to, f->ident->definition->first); if ((GetReachEnd (f->ident->definition->followinfo)) == pge_false) { return ; } break; case pge_lit: if ((SymbolKey_GetSymKey (Aliases, f->string)) == SymbolKey_NulKey) { WarnError1 ((const char *) "unknown token for '%s'", 22, f->string); WasNoError = false; } else { AddSet (to, SymbolKey_GetSymKey (Aliases, f->string)); } return ; break; case pge_sub: case pge_opt: case pge_mult: CalcFirstExpression (f->expr, from, to); break; case pge_m2: break; default: break; } f = f->next; } } /* CalcFirstTerm - */ static void CalcFirstTerm (pge_TermDesc t, pge_ProductionDesc from, pge_SetDesc *to) { while (t != NULL) { CalcFirstFactor (t->factor, from, to); t = t->next; } } /* CalcFirstExpression - */ static void CalcFirstExpression (pge_ExpressionDesc e, pge_ProductionDesc from, pge_SetDesc *to) { if (e != NULL) { CalcFirstTerm (e->term, from, to); } } /* CalcFirstStatement - */ static void CalcFirstStatement (pge_StatementDesc s, pge_ProductionDesc from, pge_SetDesc *to) { if (s != NULL) { CalcFirstExpression (s->expr, from, to); } } /* CalcFirstProduction - calculates all of the first symbols for the grammer */ static void CalcFirstProduction (pge_ProductionDesc p, pge_ProductionDesc from, pge_SetDesc *to) { pge_SetDesc s; if (p != NULL) { /* avoid gcc warning by using compound statement even if not strictly necessary. */ if (p->firstsolved) { s = p->first; while (s != NULL) { switch (s->type) { case pge_idel: CalcFirstProduction (s->ident->definition, from, to); break; case pge_tokel: case pge_litel: AddSet (to, s->string); break; default: break; } s = s->next; } } else { CalcFirstStatement (p->statement, from, to); } } } static void WorkOutFollowFactor (pge_FactorDesc f, pge_SetDesc *followset, pge_SetDesc after) { pge_TraverseResult foundepsilon; pge_TraverseResult canreachend; /* WorkOutFollow - */ foundepsilon = pge_true; canreachend = pge_true; while ((f != NULL) && (foundepsilon == pge_true)) { switch (f->type) { case pge_id: if (f->ident->definition == NULL) { WarnError1 ((const char *) "no rule found for an 'ident' called '%s'", 40, f->ident->name); M2RTS_HALT (-1); __builtin_unreachable (); } OrSet (followset, f->ident->definition->first); break; case pge_lit: AddSet (followset, SymbolKey_GetSymKey (Aliases, f->string)); break; case pge_sub: WorkOutFollowExpression (f->expr, followset, NULL); break; case pge_opt: WorkOutFollowExpression (f->expr, followset, NULL); break; case pge_mult: WorkOutFollowExpression (f->expr, followset, NULL); break; case pge_m2: break; default: break; } if ((GetEpsilon (f->followinfo)) == pge_unknown) { PushBackInput_WarnError ((const char *) "internal error: epsilon unknown", 31); PrettyCommentFactor (f, 3); WasNoError = false; } foundepsilon = GetEpsilon (f->followinfo); canreachend = GetReachEnd (f->followinfo); /* only goes from FALSE -> TRUE */ f = f->next; /* only goes from FALSE -> TRUE */ } if (canreachend == pge_true) { OrSet (followset, after); } } /* WorkOutFollowTerm - */ static void WorkOutFollowTerm (pge_TermDesc t, pge_SetDesc *followset, pge_SetDesc after) { if (t != NULL) { while (t != NULL) { WorkOutFollowFactor (t->factor, followset, after); /* { '|' Term } */ t = t->next; /* { '|' Term } */ } } } /* WorkOutFollowExpression - */ static void WorkOutFollowExpression (pge_ExpressionDesc e, pge_SetDesc *followset, pge_SetDesc after) { if (e != NULL) { WorkOutFollowTerm (e->term, followset, after); } } /* CollectFollow - collects the follow set from, f, into, to. */ static void CollectFollow (pge_SetDesc *to, pge_FollowDesc f) { OrSet (to, f->follow); } /* CalcFollowFactor - */ static void CalcFollowFactor (pge_FactorDesc f, pge_SetDesc after) { while (f != NULL) { switch (f->type) { case pge_id: WorkOutFollowFactor (f->next, &f->followinfo->follow, after); break; case pge_lit: WorkOutFollowFactor (f->next, &f->followinfo->follow, after); break; case pge_opt: case pge_sub: CalcFirstFactor (f->next, NULL, &f->followinfo->follow); if ((f->next == NULL) || ((GetReachEnd (f->next->followinfo)) == pge_true)) { OrSet (&f->followinfo->follow, after); CalcFollowExpression (f->expr, f->followinfo->follow); } else { CalcFollowExpression (f->expr, f->followinfo->follow); } break; case pge_mult: CalcFirstFactor (f, NULL, &f->followinfo->follow); /* include first as we may repeat this sentance */ if (Debugging) { StrIO_WriteLn (); StrIO_WriteString ((const char *) "found mult: and first is: ", 26); EmitSet (f->followinfo->follow, static_cast (0), static_cast (0)); StrIO_WriteLn (); } if ((f->next == NULL) || ((GetReachEnd (f->next->followinfo)) == pge_true)) { OrSet (&f->followinfo->follow, after); CalcFollowExpression (f->expr, f->followinfo->follow); } else { CalcFollowExpression (f->expr, f->followinfo->follow); } break; default: break; } f = f->next; } } /* CalcFollowTerm - */ static void CalcFollowTerm (pge_TermDesc t, pge_SetDesc after) { if (t != NULL) { while (t != NULL) { CalcFollowFactor (t->factor, after); /* { '|' Term } */ t = t->next; /* { '|' Term } */ } } } /* CalcFollowExpression - */ static void CalcFollowExpression (pge_ExpressionDesc e, pge_SetDesc after) { if (e != NULL) { CalcFollowTerm (e->term, after); } } /* CalcFollowStatement - given a bnf statement generate the follow set. */ static void CalcFollowStatement (pge_StatementDesc s) { if (s != NULL) { CalcFollowExpression (s->expr, NULL); } } /* CalcFollowProduction - */ static void CalcFollowProduction (pge_ProductionDesc p) { if (p != NULL) { CalcFollowStatement (p->statement); } } /* CalcEpsilonFactor - */ static void CalcEpsilonFactor (pge_FactorDesc f) { while (f != NULL) { switch (f->type) { case pge_id: AssignEpsilon ((GetEpsilon (f->ident->definition->followinfo)) != pge_unknown, f->followinfo, GetEpsilon (f->ident->definition->followinfo)); break; case pge_lit: AssignEpsilon (true, f->followinfo, pge_false); break; case pge_sub: CalcEpsilonExpression (f->expr); AssignEpsilon ((GetEpsilon (f->expr->followinfo)) != pge_unknown, f->followinfo, GetEpsilon (f->expr->followinfo)); break; case pge_m2: AssignEpsilon (true, f->followinfo, pge_true); break; case pge_opt: case pge_mult: CalcEpsilonExpression (f->expr); AssignEpsilon (true, f->followinfo, pge_true); break; default: break; } f = f->next; } } /* CalcEpsilonTerm - */ static void CalcEpsilonTerm (pge_TermDesc t) { if (t != NULL) { while (t != NULL) { if (t->factor != NULL) { switch (GetReachEnd (t->factor->followinfo)) { case pge_true: AssignEpsilon (true, t->followinfo, pge_true); break; case pge_false: AssignEpsilon (true, t->followinfo, pge_false); break; case pge_unknown: break; default: break; } } CalcEpsilonFactor (t->factor); /* { '|' Term } */ t = t->next; } } } /* CalcEpsilonExpression - */ static void CalcEpsilonExpression (pge_ExpressionDesc e) { pge_TermDesc t; pge_TraverseResult result; if (e != NULL) { CalcEpsilonTerm (e->term); if ((GetEpsilon (e->followinfo)) == pge_unknown) { result = pge_unknown; t = e->term; while (t != NULL) { if ((GetEpsilon (t->followinfo)) != pge_unknown) { stop (); } switch (GetEpsilon (t->followinfo)) { case pge_unknown: break; case pge_true: result = pge_true; break; case pge_false: if (result != pge_true) { result = pge_false; } break; default: break; } t = t->next; } AssignEpsilon (result != pge_unknown, e->followinfo, result); } } } /* CalcEpsilonStatement - given a bnf statement generate the follow set. */ static void CalcEpsilonStatement (pge_StatementDesc s) { if (s != NULL) { if (s->expr != NULL) { AssignEpsilon ((GetEpsilon (s->expr->followinfo)) != pge_unknown, s->followinfo, GetEpsilon (s->expr->followinfo)); } CalcEpsilonExpression (s->expr); } } /* CalcEpsilonProduction - */ static void CalcEpsilonProduction (pge_ProductionDesc p) { if (p != NULL) { /* IF p^.statement^.ident^.name=MakeKey('DefinitionModule') THEN stop END ; */ if (Debugging) { NameKey_WriteKey (p->statement->ident->name); StrIO_WriteString ((const char *) " calculating epsilon", 21); StrIO_WriteLn (); } AssignEpsilon ((GetEpsilon (p->statement->followinfo)) != pge_unknown, p->followinfo, GetEpsilon (p->statement->followinfo)); CalcEpsilonStatement (p->statement); } } /* CalcReachEndFactor - */ static pge_TraverseResult CalcReachEndFactor (pge_FactorDesc f) { pge_TraverseResult canreachend; pge_TraverseResult result; if (f == NULL) { return pge_true; /* we have reached the end of this factor list */ } else { /* we need to traverse all factors even if we can short cut the answer to this list of factors */ result = CalcReachEndFactor (f->next); switch (f->type) { case pge_id: if (f->ident->definition == NULL) { WarnError1 ((const char *) "definition for %s is absent (assuming epsilon is false for this production)", 75, f->ident->name); result = pge_false; } else if (result != pge_false) { /* avoid dangling else. */ switch (GetReachEnd (f->ident->definition->followinfo)) { case pge_false: result = pge_false; break; case pge_true: break; case pge_unknown: result = pge_unknown; break; default: break; } } break; case pge_lit: result = pge_false; break; case pge_sub: CalcReachEndExpression (f->expr); if ((f->expr != NULL) && (result == pge_true)) { result = GetReachEnd (f->expr->followinfo); } break; case pge_mult: case pge_opt: if (f->expr != NULL) { /* not interested in the result as expression is optional */ CalcReachEndExpression (f->expr); } break; case pge_m2: break; default: break; } AssignReachEnd (result != pge_unknown, f->followinfo, result); return result; } /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* CalcReachEndTerm - */ static pge_TraverseResult CalcReachEndTerm (pge_TermDesc t) { pge_TraverseResult canreachend; pge_TraverseResult result; if (t != NULL) { canreachend = pge_false; while (t != NULL) { result = CalcReachEndFactor (t->factor); AssignReachEnd (result != pge_unknown, t->followinfo, result); switch (result) { case pge_true: canreachend = pge_true; break; case pge_false: break; case pge_unknown: if (canreachend == pge_false) { canreachend = pge_unknown; } break; default: break; } t = t->next; /* { '|' Term } */ } return canreachend; } /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* CalcReachEndExpression - */ static void CalcReachEndExpression (pge_ExpressionDesc e) { pge_TraverseResult result; if (e == NULL) {} /* empty. */ else { /* no expression, thus reached the end of this sentance */ result = CalcReachEndTerm (e->term); AssignReachEnd (result != pge_unknown, e->followinfo, result); } } /* CalcReachEndStatement - */ static void CalcReachEndStatement (pge_StatementDesc s) { if (s != NULL) { if (s->expr != NULL) { CalcReachEndExpression (s->expr); AssignReachEnd ((GetReachEnd (s->expr->followinfo)) != pge_unknown, s->followinfo, GetReachEnd (s->expr->followinfo)); } } } /* CalcReachEndStatement - */ static void stop (void) { } /* CalcReachEndProduction - */ static void CalcReachEndProduction (pge_ProductionDesc p) { if (p != NULL) { CalcReachEndStatement (p->statement); if ((GetReachEnd (p->followinfo)) != pge_unknown) { if (Debugging) { StrIO_WriteString ((const char *) "already calculated reach end for: ", 34); NameKey_WriteKey (p->statement->ident->name); StrIO_WriteString ((const char *) " its value is ", 14); if ((GetReachEnd (p->followinfo)) == pge_true) { StrIO_WriteString ((const char *) "reachable", 9); } else { StrIO_WriteString ((const char *) "non reachable", 13); } StrIO_WriteLn (); } } AssignReachEnd ((GetReachEnd (p->statement->followinfo)) != pge_unknown, p->followinfo, GetReachEnd (p->statement->followinfo)); } } /* EmptyFactor - */ static bool EmptyFactor (pge_FactorDesc f) { while (f != NULL) { switch (f->type) { case pge_id: if (! (EmptyProduction (f->ident->definition))) { return false; } break; case pge_lit: return false; break; case pge_sub: if (! (EmptyExpression (f->expr))) { return false; } break; case pge_opt: case pge_mult: return true; break; case pge_m2: break; default: break; } f = f->next; } return true; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* EmptyTerm - returns TRUE if the term maybe empty. */ static bool EmptyTerm (pge_TermDesc t) { while (t != NULL) { if (EmptyFactor (t->factor)) { return true; } else { t = t->next; } } return false; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* EmptyExpression - */ static bool EmptyExpression (pge_ExpressionDesc e) { if (e == NULL) { return true; } else { return EmptyTerm (e->term); } /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* EmptyStatement - returns TRUE if statement, s, is empty. */ static bool EmptyStatement (pge_StatementDesc s) { if (s == NULL) { return true; } else { return EmptyExpression (s->expr); } /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* EmptyProduction - returns if production, p, maybe empty. */ static bool EmptyProduction (pge_ProductionDesc p) { if (p == NULL) { PushBackInput_WarnError ((const char *) "unknown production", 18); return true; } else if (p->firstsolved && (p->first != NULL)) { /* avoid dangling else. */ /* predefined but first set to something - thus not empty */ return false; } else { /* avoid dangling else. */ return EmptyStatement (p->statement); } /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* EmitFDLNotice - */ static void EmitFDLNotice (void) { Output_WriteString ((const char *) "@c Copyright (C) 2000-2023 Free Software Foundation, Inc.", 57); Output_WriteLn (); Output_WriteLn (); Output_WriteString ((const char *) "@c This file is part of GCC.", 28); Output_WriteLn (); Output_WriteString ((const char *) "@c Permission is granted to copy, distribute and/or modify this document", 72); Output_WriteLn (); Output_WriteString ((const char *) "@c under the terms of the GNU Free Documentation License, Version 1.2 or", 72); Output_WriteLn (); Output_WriteString ((const char *) "@c any later version published by the Free Software Foundation.", 63); Output_WriteLn (); } /* EmitRules - generates the BNF rules. */ static void EmitRules (void) { if (Texinfo && FreeDocLicense) { EmitFDLNotice (); } ForeachRuleDo ((pge_DoProcedure) {(pge_DoProcedure_t) EmitRule}); } /* DescribeElement - */ static void DescribeElement (unsigned int name) { NameKey_Name lit; if (InitialElement) { InitialElement = false; } else { Output_WriteString ((const char *) " |", 2); } Output_WriteLn (); Indent = 3; IndentString ((const char *) "", 0); Output_WriteKey (name); Output_WriteString ((const char *) ": ", 2); lit = static_cast (SymbolKey_GetSymKey (ReverseAliases, name)); if ((NameKey_MakeKey ((const char *) "\"", 1)) == lit) { Output_WriteString ((const char *) "str := ConCat(ConCatChar(ConCatChar(InitString(\"syntax error, found ", 68); Output_Write ('\''); Output_WriteString ((const char *) "\"), ", 4); Output_Write ('\''); Output_Write ('"'); Output_Write ('\''); Output_WriteString ((const char *) "), ", 3); Output_Write ('"'); Output_Write ('\''); Output_Write ('"'); Output_WriteString ((const char *) "), Mark(str))", 13); } else if ((NameKey_MakeKey ((const char *) "'", 1)) == lit) { /* avoid dangling else. */ Output_WriteString ((const char *) "str := ConCat(ConCatChar(ConCatChar(InitString('syntax error, found ", 68); Output_Write ('"'); Output_WriteString ((const char *) "'), ", 4); Output_Write ('"'); Output_Write ('\''); Output_Write ('"'); Output_WriteString ((const char *) "), ", 3); Output_Write ('\''); Output_Write ('"'); Output_Write ('\''); Output_WriteString ((const char *) "), Mark(str))", 13); } else { /* avoid dangling else. */ Output_WriteString ((const char *) "str := ConCat(InitString(", 25); Output_Write ('"'); Output_WriteString ((const char *) "syntax error, found ", 20); KeyWord (lit); Output_WriteString ((const char *) "\"), Mark(str))", 14); } } /* EmitInTestStop - construct a test for stop element, name. */ static void EmitInTestStop (NameKey_Name name) { unsigned int i; unsigned int value; if (LargestValue <= MaxElementsInSet) { Output_WriteKey (name); Output_WriteString ((const char *) " IN stopset", 11); ParametersUsed |= (1 << (0 )); } else { value = static_cast (SymbolKey_GetSymKey (Values, name)); i = value / MaxElementsInSet; Output_WriteKey (name); Output_WriteString ((const char *) " IN stopset", 11); Output_WriteCard (i, 0); ParametersUsed |= (1 << (i )); } } /* DescribeStopElement - */ static void DescribeStopElement (unsigned int name) { NameKey_Name lit; Indent = 3; IndentString ((const char *) "IF ", 3); EmitInTestStop (name); Output_WriteLn (); IndentString ((const char *) "THEN", 4); Output_WriteLn (); Indent = 6; lit = static_cast (SymbolKey_GetSymKey (ReverseAliases, name)); if ((lit == NameKey_NulName) || (lit == (NameKey_MakeKey ((const char *) "", 0)))) { IndentString ((const char *) "(* ", 3); Output_WriteKey (name); Output_WriteString ((const char *) " has no token name (needed to generate error messages) *)", 57); } else if ((NameKey_MakeKey ((const char *) "'", 1)) == lit) { /* avoid dangling else. */ IndentString ((const char *) "message := ConCatChar(ConCatChar(ConCatChar(ConCatChar(ConCatChar(message, ", 75); Output_WriteString ((const char *) "' '), ", 6); Output_Write ('\''); Output_Write ('"'); Output_WriteString ((const char *) "'), ", 4); Output_Write ('"'); Output_Write ('\''); Output_WriteString ((const char *) "\"), ", 4); Output_Write ('\''); Output_Write ('"'); Output_WriteString ((const char *) "'), ',') ; INC(n) ; ", 20); } else if ((NameKey_MakeKey ((const char *) "\"", 1)) == lit) { /* avoid dangling else. */ IndentString ((const char *) "message := ConCatChar(ConCatChar(ConCatChar(ConCatChar(ConCatChar(message, ", 75); Output_WriteString ((const char *) "\" \"), ", 6); Output_Write ('"'); Output_Write ('`'); Output_WriteString ((const char *) "\"), ", 4); Output_Write ('\''); Output_Write ('"'); Output_WriteString ((const char *) "'), ", 4); Output_Write ('"'); Output_Write ('\''); Output_WriteString ((const char *) "\"), \",\") ; INC(n) ; ", 20); } else { /* avoid dangling else. */ IndentString ((const char *) "message := ConCat(ConCatChar(message, ' ", 40); Output_WriteString ((const char *) "'), ", 4); Output_WriteString ((const char *) "Mark(InitString(\"", 17); KeyWord (lit); Output_Write ('"'); Output_WriteString ((const char *) "))) ; INC(n)", 12); } Output_WriteLn (); Indent = 3; IndentString ((const char *) "END ;", 5); Output_WriteLn (); } /* EmitDescribeStop - */ static void EmitDescribeStop (void) { DynamicStrings_String s; Output_WriteLn (); Indent = 0; IndentString ((const char *) "(*", 2); Indent = 3; Output_WriteLn (); IndentString ((const char *) "DescribeStop - issues a message explaining what tokens were expected", 68); Output_WriteLn (); Output_WriteString ((const char *) "*)", 2); Output_WriteLn (); Output_WriteLn (); Indent = 0; IndentString ((const char *) "PROCEDURE DescribeStop (", 24); ParametersUsed = (unsigned int) 0; Output_StartBuffer (); Output_WriteString ((const char *) ") : String ;", 12); Output_WriteLn (); IndentString ((const char *) "VAR", 3); Output_WriteLn (); Indent = 3; IndentString ((const char *) "n : CARDINAL ;", 19); Output_WriteLn (); IndentString ((const char *) "str,", 4); Output_WriteLn (); IndentString ((const char *) "message: String ;", 17); Output_WriteLn (); Indent = 0; IndentString ((const char *) "BEGIN", 5); Output_WriteLn (); Indent = 3; IndentString ((const char *) "n := 0 ;", 8); Output_WriteLn (); IndentString ((const char *) "message := InitString('') ;", 27); Output_WriteLn (); SymbolKey_ForeachNodeDo (Aliases, (SymbolKey_PerformOperation) {(SymbolKey_PerformOperation_t) DescribeStopElement}); Output_WriteLn (); Indent = 3; IndentString ((const char *) "IF n=0", 6); Output_WriteLn (); IndentString ((const char *) "THEN", 4); Output_WriteLn (); Indent = 6; IndentString ((const char *) "str := InitString(' syntax error') ; ", 37); Output_WriteLn (); IndentString ((const char *) "message := KillString(message) ; ", 33); Output_WriteLn (); Indent = 3; IndentString ((const char *) "ELSIF n=1", 9); Output_WriteLn (); IndentString ((const char *) "THEN", 4); Output_WriteLn (); Indent = 6; IndentString ((const char *) "str := ConCat(message, Mark(InitString(' missing '))) ;", 55); Output_WriteLn (); Indent = 3; IndentString ((const char *) "ELSE", 4); Output_WriteLn (); Indent = 6; IndentString ((const char *) "str := ConCat(InitString(' expecting one of'), message) ;", 57); Output_WriteLn (); IndentString ((const char *) "message := KillString(message) ;", 32); Output_WriteLn (); Indent = 3; IndentString ((const char *) "END ;", 5); Output_WriteLn (); IndentString ((const char *) "RETURN( str )", 13); Output_WriteLn (); Indent = 0; IndentString ((const char *) "END DescribeStop ;", 18); Output_WriteLn (); Output_WriteLn (); s = Output_EndBuffer (); EmitStopParameters (true); Output_KillWriteS (s); } /* EmitDescribeError - */ static void EmitDescribeError (void) { Output_WriteLn (); Indent = 0; IndentString ((const char *) "(*", 2); Output_WriteLn (); Indent = 3; IndentString ((const char *) "DescribeError - issues a message explaining what tokens were expected", 69); Output_WriteLn (); Indent = 0; IndentString ((const char *) "*)", 2); Output_WriteLn (); Output_WriteLn (); IndentString ((const char *) "PROCEDURE DescribeError ;", 25); Output_WriteLn (); IndentString ((const char *) "VAR", 3); Output_WriteLn (); Indent = 3; IndentString ((const char *) "str: String ;", 13); Output_WriteLn (); Indent = 0; IndentString ((const char *) "BEGIN", 5); Output_WriteLn (); Indent = 3; IndentString ((const char *) "str := InitString('') ;", 23); Output_WriteLn (); /* was IndentString('str := DescribeStop(') ; EmitStopParameters(FALSE) ; Output.WriteString(') ;') ; Output.WriteLn ; */ IndentString ((const char *) "CASE ", 5); WriteGetTokenType (); Output_WriteString ((const char *) " OF", 3); NewLine (3); InitialElement = true; SymbolKey_ForeachNodeDo (Aliases, (SymbolKey_PerformOperation) {(SymbolKey_PerformOperation_t) DescribeElement}); Output_WriteLn (); Indent = 3; IndentString ((const char *) "ELSE", 4); Output_WriteLn (); IndentString ((const char *) "END ;", 5); Output_WriteLn (); IndentString ((const char *) "", 0); Output_WriteKey (ErrorProcString); Output_WriteString ((const char *) "(str) ;", 7); Output_WriteLn (); Indent = 0; IndentString ((const char *) "END DescribeError ;", 19); Output_WriteLn (); } /* EmitSetTypes - write out the set types used during error recovery */ static void EmitSetTypes (void) { unsigned int i; unsigned int j; unsigned int m; unsigned int n; Output_WriteString ((const char *) "(*", 2); NewLine (3); Output_WriteString ((const char *) "expecting token set defined as an enumerated type", 49); NewLine (3); Output_WriteString ((const char *) "(", 1); i = 0; while (i < LargestValue) { Output_WriteKey (SymbolKey_GetSymKey (ReverseValues, (unsigned int ) (i))); i += 1; if (i < LargestValue) { Output_WriteString ((const char *) ", ", 2); } } Output_WriteString ((const char *) ") ;", 3); NewLine (0); Output_WriteString ((const char *) "*)", 2); NewLine (0); Output_WriteString ((const char *) "TYPE", 4); NewLine (3); if (LargestValue > MaxElementsInSet) { i = 0; n = LargestValue / MaxElementsInSet; while (i <= n) { j = i*MaxElementsInSet; if (LargestValue < (((i+1)*MaxElementsInSet)-1)) { m = LargestValue-1; } else { m = ((i+1)*MaxElementsInSet)-1; } Output_WriteString ((const char *) "stop", 4); Output_WriteCard (i, 0); Output_WriteString ((const char *) " = [", 4); Output_WriteKey (SymbolKey_GetSymKey (ReverseValues, (unsigned int ) (j))); Output_WriteString ((const char *) "..", 2); Output_WriteKey (SymbolKey_GetSymKey (ReverseValues, (unsigned int ) (m))); Output_WriteString ((const char *) "] ;", 3); NewLine (3); Output_WriteString ((const char *) "SetOfStop", 9); Output_WriteCard (i, 0); Output_WriteString ((const char *) " = SET OF stop", 14); Output_WriteCard (i, 0); Output_WriteString ((const char *) " ;", 2); NewLine (3); i += 1; } } else { Output_WriteString ((const char *) "SetOfStop", 9); Output_WriteString ((const char *) " = SET OF [", 11); Output_WriteKey (SymbolKey_GetSymKey (ReverseValues, (unsigned int ) (0))); Output_WriteString ((const char *) "..", 2); Output_WriteKey (SymbolKey_GetSymKey (ReverseValues, (unsigned int ) (LargestValue-1))); Output_WriteString ((const char *) "] ;", 3); } NewLine (0); } /* EmitSupport - generates the support routines. */ static void EmitSupport (void) { if (ErrorRecovery) { EmitSetTypes (); EmitDescribeStop (); EmitDescribeError (); } } /* DisposeSetDesc - dispose of the set list, s. */ static void DisposeSetDesc (pge_SetDesc *s) { pge_SetDesc h; pge_SetDesc n; if ((*s) != NULL) { h = (*s); n = (*s)->next; do { Storage_DEALLOCATE ((void **) &h, sizeof (pge__T7)); h = n; if (n != NULL) { n = n->next; } } while (! (h == NULL)); (*s) = NULL; } } /* OptionalFactor - */ static bool OptionalFactor (pge_FactorDesc f) { while (f != NULL) { switch (f->type) { case pge_id: break; case pge_lit: break; case pge_sub: case pge_opt: case pge_mult: if (OptionalExpression (f->expr)) { return true; } break; case pge_m2: break; default: break; } f = f->next; } return false; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* OptionalTerm - returns TRUE if the term maybe empty. */ static bool OptionalTerm (pge_TermDesc t) { pge_TermDesc u; pge_TermDesc v; pge_SetDesc tov; pge_SetDesc tou; u = t; while (u != NULL) { if (OptionalFactor (u->factor)) { return true; } v = t; tou = NULL; CalcFirstFactor (u->factor, NULL, &tou); while (v != NULL) { if (v != u) { tov = NULL; CalcFirstFactor (v->factor, NULL, &tov); if (IntersectionIsNil (tov, tou)) { DisposeSetDesc (&tov); } else { StrIO_WriteString ((const char *) "problem with two first sets. Set 1: ", 36); EmitSet (tou, static_cast (0), static_cast (0)); StrIO_WriteLn (); StrIO_WriteString ((const char *) " Set 2: ", 36); EmitSet (tov, static_cast (0), static_cast (0)); StrIO_WriteLn (); DisposeSetDesc (&tou); DisposeSetDesc (&tov); return true; } } v = v->next; } DisposeSetDesc (&tou); u = u->next; } return false; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* OptionalExpression - */ static bool OptionalExpression (pge_ExpressionDesc e) { if (e == NULL) { return false; } else { return OptionalTerm (e->term); } /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* OptionalStatement - returns FALSE if statement, s, does not have a optional ambiguity. */ static bool OptionalStatement (pge_StatementDesc s) { if (s == NULL) { return false; } else { return OptionalExpression (s->expr); } /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* OptionalProduction - */ static bool OptionalProduction (pge_ProductionDesc p) { if (p == NULL) { return false; } else { return OptionalStatement (p->statement); } /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* CheckFirstFollow - */ static bool CheckFirstFollow (pge_FactorDesc f, pge_FactorDesc after) { pge_SetDesc first; pge_SetDesc follow; first = NULL; CalcFirstFactor (f, NULL, &first); follow = NULL; follow = GetFollow (f->followinfo); if (IntersectionIsNil (first, follow)) { DisposeSetDesc (&first); DisposeSetDesc (&follow); return false; } else { PrettyCommentFactor (f, 3); NewLine (3); StrIO_WriteString ((const char *) "first: ", 7); EmitSet (first, static_cast (0), static_cast (0)); NewLine (3); StrIO_WriteString ((const char *) "follow: ", 8); EmitSet (follow, static_cast (0), static_cast (0)); NewLine (3); DisposeSetDesc (&first); DisposeSetDesc (&follow); return true; } /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* ConstrainedEmptyFactor - */ static bool ConstrainedEmptyFactor (pge_FactorDesc f) { while (f != NULL) { switch (f->type) { case pge_id: break; case pge_lit: break; case pge_sub: case pge_opt: case pge_mult: if (ConstrainedEmptyExpression (f->expr)) { return true; } break; case pge_m2: break; default: break; } if (((f->type != pge_m2) && (EmptyFactor (f))) && (CheckFirstFollow (f, f->next))) { return true; } f = f->next; } return false; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* ConstrainedEmptyTerm - returns TRUE if the term maybe empty. */ static bool ConstrainedEmptyTerm (pge_TermDesc t) { pge_SetDesc first; pge_SetDesc follow; while (t != NULL) { if (ConstrainedEmptyFactor (t->factor)) { return true; } else if (((t->factor->type != pge_m2) && (EmptyFactor (t->factor))) && (CheckFirstFollow (t->factor, t->factor->next))) { /* avoid dangling else. */ return true; } t = t->next; } return false; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* ConstrainedEmptyExpression - */ static bool ConstrainedEmptyExpression (pge_ExpressionDesc e) { if (e == NULL) { return false; } else { return ConstrainedEmptyTerm (e->term); } /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* ConstrainedEmptyStatement - returns FALSE if statement, s, does not have a optional ambiguity. */ static bool ConstrainedEmptyStatement (pge_StatementDesc s) { if (s == NULL) { return false; } else { return ConstrainedEmptyExpression (s->expr); } /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* ConstrainedEmptyProduction - returns TRUE if a problem exists with, p. */ static bool ConstrainedEmptyProduction (pge_ProductionDesc p) { if (p == NULL) { return false; } else { return ConstrainedEmptyStatement (p->statement); } /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* TestForLALR1 - */ static void TestForLALR1 (pge_ProductionDesc p) { if (OptionalProduction (p)) { WarnError1 ((const char *) "production %s has two optional sentances using | which both have the same start symbols", 87, p->statement->ident->name); WasNoError = false; PrettyCommentProduction (p); } } /* DoEpsilon - runs the epsilon interrelated rules */ static void DoEpsilon (pge_ProductionDesc p) { CalcEpsilonProduction (p); CalcReachEndProduction (p); } /* CheckComplete - checks that production, p, is complete. */ static void CheckComplete (pge_ProductionDesc p) { if ((GetReachEnd (p->followinfo)) == pge_unknown) { PrettyCommentProduction (p); 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); WasNoError = false; } } /* PostProcessRules - backpatch the ident to rule definitions and emit comments and code. */ static void PostProcessRules (void) { ForeachRuleDo ((pge_DoProcedure) {(pge_DoProcedure_t) BackPatchIdentToDefinitions}); if (! WasNoError) { M2RTS_HALT (-1); __builtin_unreachable (); } WhileNotCompleteDo ((pge_DoProcedure) {(pge_DoProcedure_t) DoEpsilon}); if (! WasNoError) { M2RTS_HALT (-1); __builtin_unreachable (); } ForeachRuleDo ((pge_DoProcedure) {(pge_DoProcedure_t) CheckComplete}); if (! WasNoError) { M2RTS_HALT (-1); __builtin_unreachable (); } WhileNotCompleteDo ((pge_DoProcedure) {(pge_DoProcedure_t) CalculateFirstAndFollow}); if (! WasNoError) { M2RTS_HALT (-1); __builtin_unreachable (); } ForeachRuleDo ((pge_DoProcedure) {(pge_DoProcedure_t) TestForLALR1}); if (! WasNoError) { ForeachRuleDo ((pge_DoProcedure) {(pge_DoProcedure_t) PrettyCommentProduction}); } } /* DisplayHelp - display a summary help and then exit (0). */ static void DisplayHelp (void) { StrIO_WriteString ((const char *) "Usage: pge [-l] [-c] [-d] [-e] [-k] [-t] [-k] [-p] [-x] [-f] [-o outputfile] filename", 85); StrIO_WriteLn (); StrIO_WriteString ((const char *) " -l suppress file and line source information", 59); StrIO_WriteLn (); StrIO_WriteString ((const char *) " -c do not generate any Modula-2 code within the parser rules", 75); StrIO_WriteLn (); StrIO_WriteString ((const char *) " -h or --help generate this help message", 44); StrIO_WriteLn (); StrIO_WriteString ((const char *) " -e do not generate a parser with error recovery", 62); StrIO_WriteLn (); StrIO_WriteString ((const char *) " -k generate keyword errors with GCC formatting directives", 72); StrIO_WriteLn (); StrIO_WriteString ((const char *) " -d generate internal debugging information", 57); StrIO_WriteLn (); StrIO_WriteString ((const char *) " -p only display the ebnf rules", 45); StrIO_WriteLn (); StrIO_WriteString ((const char *) " -t generate texinfo formating for pretty printing (-p)", 69); StrIO_WriteLn (); StrIO_WriteString ((const char *) " -x generate sphinx formating for pretty printing (-p)", 68); StrIO_WriteLn (); StrIO_WriteString ((const char *) " -f generate GNU Free Documentation header before pretty printing in texinfo", 90); StrIO_WriteLn (); StrIO_WriteString ((const char *) " -o write output to filename", 42); StrIO_WriteLn (); libc_exit (0); } /* ParseArgs - */ static void ParseArgs (void) { unsigned int n; unsigned int i; ErrorRecovery = true; /* DefaultRecovery ; */ Debugging = false; /* DefaultRecovery ; */ PrettyPrint = false; KeywordFormatting = false; i = 1; n = Args_Narg (); while (i < n) { if (Args_GetArg ((char *) &ArgName.array[0], MaxFileName, i)) { /* avoid gcc warning by using compound statement even if not strictly necessary. */ if (StrLib_StrEqual ((const char *) &ArgName.array[0], MaxFileName, (const char *) "-e", 2)) { ErrorRecovery = false; } else if (StrLib_StrEqual ((const char *) &ArgName.array[0], MaxFileName, (const char *) "-d", 2)) { /* avoid dangling else. */ Debugging = true; bnflex_SetDebugging (true); } else if (StrLib_StrEqual ((const char *) &ArgName.array[0], MaxFileName, (const char *) "-c", 2)) { /* avoid dangling else. */ EmitCode = false; } else if (StrLib_StrEqual ((const char *) &ArgName.array[0], MaxFileName, (const char *) "-k", 2)) { /* avoid dangling else. */ KeywordFormatting = true; } else if (StrLib_StrEqual ((const char *) &ArgName.array[0], MaxFileName, (const char *) "-l", 2)) { /* avoid dangling else. */ SuppressFileLineTag = true; } 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))) { /* avoid dangling else. */ DisplayHelp (); } else if (StrLib_StrEqual ((const char *) &ArgName.array[0], MaxFileName, (const char *) "-p", 2)) { /* avoid dangling else. */ PrettyPrint = true; } else if (StrLib_StrEqual ((const char *) &ArgName.array[0], MaxFileName, (const char *) "-t", 2)) { /* avoid dangling else. */ Texinfo = true; } else if (StrLib_StrEqual ((const char *) &ArgName.array[0], MaxFileName, (const char *) "-x", 2)) { /* avoid dangling else. */ Sphinx = true; } else if (StrLib_StrEqual ((const char *) &ArgName.array[0], MaxFileName, (const char *) "-f", 2)) { /* avoid dangling else. */ FreeDocLicense = true; } else if (StrLib_StrEqual ((const char *) &ArgName.array[0], MaxFileName, (const char *) "-o", 2)) { /* avoid dangling else. */ i += 1; if (Args_GetArg ((char *) &ArgName.array[0], MaxFileName, i)) { if (! (Output_Open ((const char *) &ArgName.array[0], MaxFileName))) { StrIO_WriteString ((const char *) "cannot open ", 12); StrIO_WriteString ((const char *) &ArgName.array[0], MaxFileName); StrIO_WriteString ((const char *) " for writing", 12); StrIO_WriteLn (); libc_exit (1); } } } else if (bnflex_OpenSource ((const char *) &ArgName.array[0], MaxFileName)) { /* avoid dangling else. */ StrLib_StrCopy ((const char *) &ArgName.array[0], MaxFileName, (char *) &FileName.array[0], MaxFileName); bnflex_AdvanceToken (); } else { /* avoid dangling else. */ StrIO_WriteString ((const char *) "cannot open ", 12); StrIO_WriteString ((const char *) &ArgName.array[0], MaxFileName); StrIO_WriteString ((const char *) " for reading", 12); StrIO_WriteLn (); libc_exit (1); } } i += 1; } if (n == 1) { DisplayHelp (); } } /* Init - initialize the modules data structures */ static void Init (void) { WasNoError = true; Texinfo = false; Sphinx = false; FreeDocLicense = false; EmitCode = true; LargestValue = 0; HeadProduction = NULL; CurrentProduction = NULL; SymbolKey_InitTree (&Aliases); SymbolKey_InitTree (&ReverseAliases); SymbolKey_InitTree (&Values); SymbolKey_InitTree (&ReverseValues); LastLineNo = 0; CodePrologue = NULL; CodeEpilogue = NULL; CodeDeclaration = NULL; ErrorProcArray = NameKey_MakeKey ((const char *) "Error", 5); ErrorProcString = NameKey_MakeKey ((const char *) "ErrorS", 6); TokenTypeProc = NameKey_MakeKey ((const char *) "GetCurrentTokenType()", 21); SymIsProc = NameKey_MakeKey ((const char *) "SymIs", 5); OnLineStart = true; ParseArgs (); Main (static_cast ((unsigned int) ((1 << (bnflex_eoftok))))); /* this line will be manipulated by sed in buildpg */ if (WasNoError) /* this line will be manipulated by sed in buildpg */ { PostProcessRules (); if (WasNoError) { /* avoid gcc warning by using compound statement even if not strictly necessary. */ if (Debugging) { EmitRules (); } else if (PrettyPrint) { /* avoid dangling else. */ EmitRules (); } else { /* avoid dangling else. */ Output_WriteString ((const char *) "(* it is advisable not to edit this file as it was automatically generated from the grammer file ", 97); Output_WriteString ((const char *) &FileName.array[0], MaxFileName); Output_WriteString ((const char *) " *)", 3); Output_WriteLn (); OnLineStart = false; EmitFileLineTag (LinePrologue); BeginningOfLine = true; WriteCodeHunkList (CodePrologue); EmitSupport (); EmitFileLineTag (LineDeclaration); WriteCodeHunkList (CodeDeclaration); EmitRules (); /* code rules */ EmitFileLineTag (LineEpilogue); WriteCodeHunkList (CodeEpilogue); } } } Output_Close (); } extern "C" void _M2_pge_init (__attribute__((unused)) int argc,__attribute__((unused)) char *argv[],__attribute__((unused)) char *envp[]) { Init (); } extern "C" void _M2_pge_fini (__attribute__((unused)) int argc,__attribute__((unused)) char *argv[],__attribute__((unused)) char *envp[]) { }