| /* do not edit automatically generated by mc from bnflex. */ |
| /* bnflex.mod provides a simple lexical package for pg. |
| |
| Copyright (C) 2001-2026 Free Software Foundation, Inc. |
| Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>. |
| |
| 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 |
| <http://www.gnu.org/licenses/>. */ |
| |
| #include <stdbool.h> |
| # 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 <string.h> |
| #include <limits.h> |
| #define _bnflex_C |
| |
| #include "Gbnflex.h" |
| # include "GPushBackInput.h" |
| # include "GSymbolKey.h" |
| # include "GASCII.h" |
| # include "GDebug.h" |
| # include "GNameKey.h" |
| # include "GStrLib.h" |
| # include "GFIO.h" |
| # include "GStrCase.h" |
| # include "GStdIO.h" |
| |
| # define MaxNameLength 8192 |
| static FIO_File f; |
| static SymbolKey_SymbolTree ReservedWords; |
| static NameKey_Name CurrentToken; |
| static bnflex_TokenType CurrentType; |
| static bool Debugging; |
| static bool InQuote; |
| static char QuoteChar; |
| |
| /* |
| OpenSource - Attempts to open the source file, a. |
| The success of the operation is returned. |
| */ |
| |
| extern "C" bool bnflex_OpenSource (const char *a_, unsigned int _a_high); |
| |
| /* |
| CloseSource - Closes the current open file. |
| */ |
| |
| extern "C" void bnflex_CloseSource (void); |
| |
| /* |
| GetChar - returns the current character on the input stream. |
| */ |
| |
| extern "C" char bnflex_GetChar (void); |
| |
| /* |
| PutChar - pushes a character onto the push back stack, it also |
| returns the character which has been pushed. |
| */ |
| |
| extern "C" char bnflex_PutChar (char ch); |
| |
| /* |
| SymIs - if t is equal to the current token the next token is read |
| and true is returned, otherwise false is returned. |
| */ |
| |
| extern "C" bool bnflex_SymIs (bnflex_TokenType t); |
| |
| /* |
| IsSym - returns the result of the comparison between the current token |
| type and t. |
| */ |
| |
| extern "C" bool bnflex_IsSym (bnflex_TokenType t); |
| |
| /* |
| GetCurrentTokenType - returns the type of current token. |
| */ |
| |
| extern "C" bnflex_TokenType bnflex_GetCurrentTokenType (void); |
| |
| /* |
| GetCurrentToken - returns the NameKey of the current token. |
| */ |
| |
| extern "C" NameKey_Name bnflex_GetCurrentToken (void); |
| |
| /* |
| SkipUntilWhite - skips all characters until white space is seen. |
| */ |
| |
| extern "C" void bnflex_SkipUntilWhite (void); |
| |
| /* |
| SkipWhite - skips all white space. |
| */ |
| |
| extern "C" void bnflex_SkipWhite (void); |
| |
| /* |
| SkipUntilEoln - skips until a lf is seen. It consumes the lf. |
| */ |
| |
| extern "C" void bnflex_SkipUntilEoln (void); |
| |
| /* |
| AdvanceToken - advances to the next token. |
| */ |
| |
| extern "C" void bnflex_AdvanceToken (void); |
| |
| /* |
| IsReserved - returns TRUE if the name is a reserved word. |
| */ |
| |
| extern "C" bool bnflex_IsReserved (NameKey_Name name); |
| |
| /* |
| PushBackToken - pushes a token back onto input. |
| */ |
| |
| extern "C" void bnflex_PushBackToken (NameKey_Name t); |
| |
| /* |
| SetDebugging - sets the debugging flag. |
| */ |
| |
| extern "C" void bnflex_SetDebugging (bool flag); |
| |
| /* |
| EatChar - consumes the next character in the input. |
| */ |
| |
| static void EatChar (void); |
| |
| /* |
| IsWhite - returns TRUE if, ch, is a space or a tab. |
| */ |
| |
| static bool IsWhite (char ch); |
| |
| /* |
| SkipComments - consumes comments. |
| */ |
| |
| static void SkipComments (void); |
| |
| /* |
| WriteToken - |
| */ |
| |
| static void WriteToken (void); |
| |
| /* |
| Init - initialize the modules global variables. |
| */ |
| |
| static void Init (void); |
| |
| |
| /* |
| EatChar - consumes the next character in the input. |
| */ |
| |
| static void EatChar (void) |
| { |
| if ((PushBackInput_GetCh (f)) == ASCII_nul) |
| {} /* empty. */ |
| } |
| |
| |
| /* |
| 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 (); |
| } |
| |
| |
| /* |
| SkipComments - consumes comments. |
| */ |
| |
| static void SkipComments (void) |
| { |
| bnflex_SkipWhite (); |
| while ((bnflex_PutChar (bnflex_GetChar ())) == '-') |
| { |
| if (((bnflex_GetChar ()) == '-') && ((bnflex_PutChar (bnflex_GetChar ())) == '-')) |
| { |
| /* found comment, skip it */ |
| bnflex_SkipUntilEoln (); |
| bnflex_SkipWhite (); |
| } |
| else |
| { |
| /* no second '-' found thus restore first '-' */ |
| if ((bnflex_PutChar ('-')) == '-') |
| {} /* empty. */ |
| return ; |
| } |
| } |
| } |
| |
| |
| /* |
| WriteToken - |
| */ |
| |
| static void WriteToken (void) |
| { |
| NameKey_WriteKey (CurrentToken); |
| StdIO_Write (' '); |
| } |
| |
| |
| /* |
| Init - initialize the modules global variables. |
| */ |
| |
| static void Init (void) |
| { |
| typedef struct Init__T1_a Init__T1; |
| |
| struct Init__T1_a { char array[1+1]; }; |
| Init__T1 a; |
| |
| SymbolKey_InitTree (&ReservedWords); |
| Debugging = false; |
| a.array[0] = ASCII_nul; |
| SymbolKey_PutSymKey (ReservedWords, NameKey_MakeKey ((const char *) &a.array[0], 1), ((unsigned int) (bnflex_eoftok))); |
| SymbolKey_PutSymKey (ReservedWords, NameKey_MakeKey ((const char *) "%", 1), ((unsigned int) (bnflex_codetok))); |
| SymbolKey_PutSymKey (ReservedWords, NameKey_MakeKey ((const char *) ":=", 2), ((unsigned int) (bnflex_lbecomestok))); |
| SymbolKey_PutSymKey (ReservedWords, NameKey_MakeKey ((const char *) "=:", 2), ((unsigned int) (bnflex_rbecomestok))); |
| SymbolKey_PutSymKey (ReservedWords, NameKey_MakeKey ((const char *) "|", 1), ((unsigned int) (bnflex_bartok))); |
| SymbolKey_PutSymKey (ReservedWords, NameKey_MakeKey ((const char *) "[", 1), ((unsigned int) (bnflex_lsparatok))); |
| SymbolKey_PutSymKey (ReservedWords, NameKey_MakeKey ((const char *) "]", 1), ((unsigned int) (bnflex_rsparatok))); |
| SymbolKey_PutSymKey (ReservedWords, NameKey_MakeKey ((const char *) "{", 1), ((unsigned int) (bnflex_lcparatok))); |
| SymbolKey_PutSymKey (ReservedWords, NameKey_MakeKey ((const char *) "}", 1), ((unsigned int) (bnflex_rcparatok))); |
| SymbolKey_PutSymKey (ReservedWords, NameKey_MakeKey ((const char *) "(", 1), ((unsigned int) (bnflex_lparatok))); |
| SymbolKey_PutSymKey (ReservedWords, NameKey_MakeKey ((const char *) ")", 1), ((unsigned int) (bnflex_rparatok))); |
| SymbolKey_PutSymKey (ReservedWords, NameKey_MakeKey ((const char *) "<", 1), ((unsigned int) (bnflex_lesstok))); |
| SymbolKey_PutSymKey (ReservedWords, NameKey_MakeKey ((const char *) ">", 1), ((unsigned int) (bnflex_gretok))); |
| SymbolKey_PutSymKey (ReservedWords, NameKey_MakeKey ((const char *) "error", 5), ((unsigned int) (bnflex_errortok))); |
| SymbolKey_PutSymKey (ReservedWords, NameKey_MakeKey ((const char *) "tokenfunc", 9), ((unsigned int) (bnflex_tfunctok))); |
| SymbolKey_PutSymKey (ReservedWords, NameKey_MakeKey ((const char *) "symfunc", 7), ((unsigned int) (bnflex_symfunctok))); |
| SymbolKey_PutSymKey (ReservedWords, NameKey_MakeKey ((const char *) "'", 1), ((unsigned int) (bnflex_squotetok))); |
| SymbolKey_PutSymKey (ReservedWords, NameKey_MakeKey ((const char *) "\"", 1), ((unsigned int) (bnflex_dquotetok))); |
| SymbolKey_PutSymKey (ReservedWords, NameKey_MakeKey ((const char *) "module", 6), ((unsigned int) (bnflex_moduletok))); |
| SymbolKey_PutSymKey (ReservedWords, NameKey_MakeKey ((const char *) "begin", 5), ((unsigned int) (bnflex_begintok))); |
| SymbolKey_PutSymKey (ReservedWords, NameKey_MakeKey ((const char *) "rules", 5), ((unsigned int) (bnflex_rulestok))); |
| SymbolKey_PutSymKey (ReservedWords, NameKey_MakeKey ((const char *) "end", 3), ((unsigned int) (bnflex_endtok))); |
| SymbolKey_PutSymKey (ReservedWords, NameKey_MakeKey ((const char *) "declaration", 11), ((unsigned int) (bnflex_declarationtok))); |
| SymbolKey_PutSymKey (ReservedWords, NameKey_MakeKey ((const char *) "token", 5), ((unsigned int) (bnflex_tokentok))); |
| SymbolKey_PutSymKey (ReservedWords, NameKey_MakeKey ((const char *) "special", 7), ((unsigned int) (bnflex_specialtok))); |
| SymbolKey_PutSymKey (ReservedWords, NameKey_MakeKey ((const char *) "first", 5), ((unsigned int) (bnflex_firsttok))); |
| SymbolKey_PutSymKey (ReservedWords, NameKey_MakeKey ((const char *) "follow", 6), ((unsigned int) (bnflex_followtok))); |
| SymbolKey_PutSymKey (ReservedWords, NameKey_MakeKey ((const char *) "epsilon", 7), ((unsigned int) (bnflex_epsilontok))); |
| SymbolKey_PutSymKey (ReservedWords, NameKey_MakeKey ((const char *) "BNF", 3), ((unsigned int) (bnflex_BNFtok))); |
| SymbolKey_PutSymKey (ReservedWords, NameKey_MakeKey ((const char *) "FNB", 3), ((unsigned int) (bnflex_FNBtok))); |
| CurrentToken = NameKey_NulName; |
| CurrentType = bnflex_identtok; |
| InQuote = false; |
| } |
| |
| |
| /* |
| OpenSource - Attempts to open the source file, a. |
| The success of the operation is returned. |
| */ |
| |
| extern "C" bool bnflex_OpenSource (const char *a_, unsigned int _a_high) |
| { |
| char a[_a_high+1]; |
| |
| /* make a local copy of each unbounded array. */ |
| memcpy (a, a_, _a_high+1); |
| |
| f = PushBackInput_Open ((const char *) a, _a_high); |
| return FIO_IsNoError (f); |
| /* static analysis guarentees a RETURN statement will be used before here. */ |
| __builtin_unreachable (); |
| } |
| |
| |
| /* |
| CloseSource - Closes the current open file. |
| */ |
| |
| extern "C" void bnflex_CloseSource (void) |
| { |
| PushBackInput_Close (f); |
| } |
| |
| |
| /* |
| GetChar - returns the current character on the input stream. |
| */ |
| |
| extern "C" char bnflex_GetChar (void) |
| { |
| return PushBackInput_GetCh (f); |
| /* static analysis guarentees a RETURN statement will be used before here. */ |
| __builtin_unreachable (); |
| } |
| |
| |
| /* |
| PutChar - pushes a character onto the push back stack, it also |
| returns the character which has been pushed. |
| */ |
| |
| extern "C" char bnflex_PutChar (char ch) |
| { |
| return PushBackInput_PutCh (ch); |
| /* static analysis guarentees a RETURN statement will be used before here. */ |
| __builtin_unreachable (); |
| } |
| |
| |
| /* |
| SymIs - if t is equal to the current token the next token is read |
| and true is returned, otherwise false is returned. |
| */ |
| |
| extern "C" bool bnflex_SymIs (bnflex_TokenType t) |
| { |
| if (CurrentType == t) |
| { |
| bnflex_AdvanceToken (); |
| return true; |
| } |
| else |
| { |
| return false; |
| } |
| /* static analysis guarentees a RETURN statement will be used before here. */ |
| __builtin_unreachable (); |
| } |
| |
| |
| /* |
| IsSym - returns the result of the comparison between the current token |
| type and t. |
| */ |
| |
| extern "C" bool bnflex_IsSym (bnflex_TokenType t) |
| { |
| return t == CurrentType; |
| /* static analysis guarentees a RETURN statement will be used before here. */ |
| __builtin_unreachable (); |
| } |
| |
| |
| /* |
| GetCurrentTokenType - returns the type of current token. |
| */ |
| |
| extern "C" bnflex_TokenType bnflex_GetCurrentTokenType (void) |
| { |
| return CurrentType; |
| /* static analysis guarentees a RETURN statement will be used before here. */ |
| __builtin_unreachable (); |
| } |
| |
| |
| /* |
| GetCurrentToken - returns the NameKey of the current token. |
| */ |
| |
| extern "C" NameKey_Name bnflex_GetCurrentToken (void) |
| { |
| return CurrentToken; |
| /* static analysis guarentees a RETURN statement will be used before here. */ |
| __builtin_unreachable (); |
| } |
| |
| |
| /* |
| SkipUntilWhite - skips all characters until white space is seen. |
| */ |
| |
| extern "C" void bnflex_SkipUntilWhite (void) |
| { |
| while (((! (IsWhite (bnflex_PutChar (bnflex_GetChar ())))) && ((bnflex_PutChar (bnflex_GetChar ())) != ASCII_nul)) || ((bnflex_PutChar (bnflex_GetChar ())) == ASCII_lf)) |
| { |
| EatChar (); |
| } |
| } |
| |
| |
| /* |
| SkipWhite - skips all white space. |
| */ |
| |
| extern "C" void bnflex_SkipWhite (void) |
| { |
| while (IsWhite (bnflex_PutChar (bnflex_GetChar ()))) |
| { |
| EatChar (); |
| } |
| } |
| |
| |
| /* |
| SkipUntilEoln - skips until a lf is seen. It consumes the lf. |
| */ |
| |
| extern "C" void bnflex_SkipUntilEoln (void) |
| { |
| while (((bnflex_PutChar (bnflex_GetChar ())) != ASCII_lf) && ((bnflex_PutChar (bnflex_GetChar ())) != ASCII_nul)) |
| { |
| EatChar (); |
| } |
| if ((bnflex_PutChar (bnflex_GetChar ())) == ASCII_lf) |
| { |
| EatChar (); |
| } |
| } |
| |
| |
| /* |
| AdvanceToken - advances to the next token. |
| */ |
| |
| extern "C" void bnflex_AdvanceToken (void) |
| { |
| typedef struct AdvanceToken__T2_a AdvanceToken__T2; |
| |
| struct AdvanceToken__T2_a { char array[MaxNameLength+1]; }; |
| AdvanceToken__T2 a; |
| unsigned int i; |
| |
| i = 0; |
| if (InQuote) |
| { |
| if (CurrentType == bnflex_literaltok) |
| { |
| if ((bnflex_PutChar (bnflex_GetChar ())) == QuoteChar) |
| { |
| a.array[i] = bnflex_GetChar (); |
| InQuote = false; |
| i += 1; |
| a.array[i] = ASCII_nul; |
| CurrentToken = NameKey_MakeKey ((const char *) &a.array[0], MaxNameLength); |
| CurrentType = (bnflex_TokenType) (SymbolKey_GetSymKey (ReservedWords, CurrentToken)); |
| } |
| else |
| { |
| if (QuoteChar == '"') |
| { |
| PushBackInput_WarnError ((const char *) "missing \" at the end of a literal", 33); |
| } |
| else |
| { |
| PushBackInput_WarnError ((const char *) "missing ' at the end of a literal", 33); |
| } |
| InQuote = false; /* to avoid a contineous list of the same error message */ |
| } |
| } |
| else |
| { |
| while ((((i < MaxNameLength) && ((bnflex_PutChar (bnflex_GetChar ())) != ASCII_nul)) && ((bnflex_PutChar (bnflex_GetChar ())) != ASCII_lf)) && ((bnflex_PutChar (bnflex_GetChar ())) != QuoteChar)) |
| { |
| a.array[i] = bnflex_GetChar (); |
| i += 1; |
| } |
| if ((bnflex_PutChar (bnflex_GetChar ())) == QuoteChar) |
| { |
| CurrentType = bnflex_literaltok; |
| a.array[i] = ASCII_nul; |
| CurrentToken = NameKey_MakeKey ((const char *) &a.array[0], MaxNameLength); |
| } |
| else |
| { |
| if (QuoteChar == '"') |
| { |
| PushBackInput_WarnError ((const char *) "missing \" at the end of a literal", 33); |
| } |
| else |
| { |
| PushBackInput_WarnError ((const char *) "missing ' at the end of a literal", 33); |
| } |
| InQuote = false; /* to avoid a contineous list of the same error message */ |
| } |
| } |
| } |
| else |
| { |
| SkipComments (); |
| if (((bnflex_PutChar (bnflex_GetChar ())) == '"') || ((bnflex_PutChar (bnflex_GetChar ())) == '\'')) |
| { |
| a.array[i] = bnflex_GetChar (); |
| QuoteChar = a.array[i]; |
| i += 1; |
| InQuote = true; |
| a.array[i] = ASCII_nul; |
| CurrentToken = NameKey_MakeKey ((const char *) &a.array[0], MaxNameLength); |
| CurrentType = (bnflex_TokenType) (SymbolKey_GetSymKey (ReservedWords, CurrentToken)); |
| } |
| else |
| { |
| while (((((i < MaxNameLength) && ((bnflex_PutChar (bnflex_GetChar ())) != ASCII_nul)) && ((bnflex_PutChar (bnflex_GetChar ())) != ASCII_lf)) && ((bnflex_PutChar (bnflex_GetChar ())) != QuoteChar)) && (! (IsWhite (bnflex_PutChar (bnflex_GetChar ()))))) |
| { |
| a.array[i] = bnflex_GetChar (); |
| i += 1; |
| } |
| a.array[i] = ASCII_nul; |
| CurrentToken = NameKey_MakeKey ((const char *) &a.array[0], MaxNameLength); |
| if ((SymbolKey_GetSymKey (ReservedWords, CurrentToken)) == 0) |
| { |
| CurrentType = bnflex_identtok; |
| } |
| else |
| { |
| CurrentType = (bnflex_TokenType) (SymbolKey_GetSymKey (ReservedWords, CurrentToken)); |
| } |
| } |
| } |
| if (Debugging) |
| { |
| WriteToken (); |
| } |
| } |
| |
| |
| /* |
| IsReserved - returns TRUE if the name is a reserved word. |
| */ |
| |
| extern "C" bool bnflex_IsReserved (NameKey_Name name) |
| { |
| return (SymbolKey_GetSymKey (ReservedWords, name)) != 0; |
| /* static analysis guarentees a RETURN statement will be used before here. */ |
| __builtin_unreachable (); |
| } |
| |
| |
| /* |
| PushBackToken - pushes a token back onto input. |
| */ |
| |
| extern "C" void bnflex_PushBackToken (NameKey_Name t) |
| { |
| typedef struct PushBackToken__T3_a PushBackToken__T3; |
| |
| struct PushBackToken__T3_a { char array[MaxNameLength+1]; }; |
| PushBackToken__T3 a; |
| |
| NameKey_GetKey (t, (char *) &a.array[0], MaxNameLength); |
| PushBackInput_PutString ((const char *) &a.array[0], MaxNameLength); |
| } |
| |
| |
| /* |
| SetDebugging - sets the debugging flag. |
| */ |
| |
| extern "C" void bnflex_SetDebugging (bool flag) |
| { |
| Debugging = flag; |
| } |
| |
| extern "C" void _M2_bnflex_init (__attribute__((unused)) int argc,__attribute__((unused)) char *argv[],__attribute__((unused)) char *envp[]) |
| { |
| Init (); |
| } |
| |
| extern "C" void _M2_bnflex_fini (__attribute__((unused)) int argc,__attribute__((unused)) char *argv[],__attribute__((unused)) char *envp[]) |
| { |
| } |