Version 7.0
Copyright © 2021 Lowell D. Thomas
APG
… an ABNF Parser Generator
main.c
Go to the documentation of this file.
1 /* *************************************************************************************
2  Copyright (c) 2021, Lowell D. Thomas
3  All rights reserved.
4 
5  This file is part of APG Version 7.0.
6  APG Version 7.0 may be used under the terms of the BSD 2-Clause License.
7 
8  Redistribution and use in source and binary forms, with or without
9  modification, are permitted provided that the following conditions are met:
10 
11  1. Redistributions of source code must retain the above copyright notice, this
12  list of conditions and the following disclaimer.
13 
14  2. Redistributions in binary form must reproduce the above copyright notice,
15  this list of conditions and the following disclaimer in the documentation
16  and/or other materials provided with the distribution.
17 
18  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 
29 * *************************************************************************************/
46 #include "../api/api.h"
47 #include "../api/apip.h"
48 #include "../api/attributes.h"
49 #include "../api/semantics.h"
50 #include "./config.h"
51 #include "../library/parserp.h"
52 
61 int main(int argc, char **argv) {
62  static void* vpApi = NULL;
63  static void* vpCfg = NULL;
64  static void* vpMem = NULL;
65  const config* spConfig;
66  aint ui;
67  const char* cpGrammar;
68  exception e;
69 
70  XCTOR(e);
71  if(!e.try){
72  // catch block
73  printf("APG CATCH BLOCK\n");
74  if(vpMem){
75  // display the exception info
76  printf("EXCEPTION INFORMATION\n");
78  if(vpApi){
79  void* vpLog = vpApiGetErrorLog(vpApi);
80  vUtilPrintMsgs(vpLog);
81  }
82  }else{
83  printf("memory allocation error\n");
84  }
85 
86  // clean up all memory, if any
87  vApiDtor(vpApi);
88  vMemDtor(vpMem);
89  return EXIT_FAILURE;
90  }
91 
92  vpMem = vpMemCtor(&e);
93  while (APG_TRUE) {
94  // constructors (note: in release build these will be reset to NULL by setjmp() in catch block)
95  vpCfg = vpConfigCtor(&e);
96  vpApi = vpApiCtor(&e);
97 
98  // get the configuration and go
99  spConfig = spConfigOptions(vpCfg, argc, argv);
100  if (spConfig->bDc) {
101  vConfigDisplay(spConfig, argc, argv);
102  printf("\n");
103  }
104 
105  if (spConfig->bHelp) {
106  vConfigHelp();
107  break;
108  }
109  if (spConfig->bVersion) {
110  vConfigVersion();
111  break;
112  }
113  if (spConfig->cpDefaultConfig) {
114  vConfigDefault(vpCfg, spConfig->cpDefaultConfig);
115  break;
116  }
117 
118  // get the grammar file
119  if (!spConfig->uiInputFiles) {
120  XTHROW(&e, "no input file specified, use --input=filename");
121  }
122  for (ui = 0; ui < spConfig->uiInputFiles; ui += 1) {
123  cpGrammar = cpApiInFile(vpApi, spConfig->cppInput[ui]);
124  }
125  if (spConfig->bDg) {
126  vApiInToAscii(vpApi, NULL);
127  }
128  if (spConfig->cpGrammarHtml) {
129  vApiInToHtml(vpApi, spConfig->cpGrammarHtml, NULL);
130  printf("HTML formatted grammar written to \"%s\"\n", spConfig->cpGrammarHtml);
131  printf("\n");
132  }
133  if (spConfig->cpLfOut || spConfig->cpCrLfOut) {
134  if (spConfig->cpLfOut) {
135  vUtilConvertLineEnds(&e, cpGrammar, "\n", spConfig->cpLfOut);
136  printf("line ends of input converted to LF at: %s\n", spConfig->cpLfOut);
137  }
138  if (spConfig->cpCrLfOut) {
139  vUtilConvertLineEnds(&e, cpGrammar, "\r\n", spConfig->cpCrLfOut);
140  printf("line ends of input converted to CRLF at: %s\n", spConfig->cpCrLfOut);
141  }
142  break;
143  }
144 
145  // API - validate the grammar - validation phase
146  vApiInValidate(vpApi, spConfig->bStrict);
147 
148  // API - parse the grammar - syntax phase
149  vApiSyntax(vpApi, spConfig->bStrict);
150 
151  // API - traverse the AST - semantic phase
152  vApiOpcodes(vpApi);
153 
154  if (spConfig->bDr) {
155  vApiRulesToAscii(vpApi, "index", NULL);
156  }
157  if (spConfig->bDra) {
158  vApiRulesToAscii(vpApi, "alpha", NULL);
159  }
160  if (spConfig->bDp) {
161  pppt_size sSize;
162  vApiPpptSize(vpApi, &sSize);
163  printf("PPPT SIZES\n");
164  printf(" alphabet min char: %"PRIuMAX"\n", sSize.luiAcharMin);
165  printf(" alphabet max char: %"PRIuMAX"\n", sSize.luiAcharMax);
166  printf("number of PPPT maps: %"PRIuMAX"\n", sSize.luiMaps);
167  printf(" PPPT map size: %"PRIuMAX"\n", sSize.luiMapSize);
168  if(sSize.luiTableSize == APG_MAX_AINT){
169  printf(" PPPT total size: OVERFLOW\n");
170  }else{
171  printf(" PPPT total size: %"PRIuMAX"\n", sSize.luiTableSize);
172  }
173  printf("\n");
174  }
175  if (spConfig->bDo) {
176  vApiOpcodesToAscii(vpApi, NULL);
177  }
178 
179  // API - get the attributes - attribute phase
180  if(bApiAttrs(vpApi)){
181  if (spConfig->bDa) {
182  vApiAttrsToAscii(vpApi, "type", NULL);
183  }
184  }else{
185  printf("ATTRIBUTE ERRORS DETECTED\n");
186  vApiAttrsErrorsToAscii(vpApi, "type", NULL);
187  if (spConfig->bDa) {
188  printf("\n");
189  vApiAttrsToAscii(vpApi, "type", NULL);
190  }
191  break;
192  }
193 
194  // PPPT
195  if(!spConfig->bNoPppt){
196  vApiPppt(vpApi, spConfig->cppPRules, spConfig->uiPRules);
197  }
198 
199  // output the parser files
200  if (spConfig->cpOutput) {
201  vApiOutput(vpApi, spConfig->cpOutput);
202  printf("generated parser output to: %s\n", spConfig->cpOutput);
203  }
204  break;
205  }
206 
207  // clean up API exception block
208  vApiDtor(vpApi);
209  vConfigDtor(vpCfg);
210  vMemDtor(vpMem);
211  return EXIT_SUCCESS;
212 }
213 
vConfigDefault
void vConfigDefault(void *vpCtx, char *cpFileName)
Prints a default configuration file.
Definition: config.c:282
XCTOR
#define XCTOR(e)
This macro will initialize an exception structure and prepare entry to the "try" block.
Definition: exception.h:77
config::cppInput
char ** cppInput
array of uiInputFiles input file names
Definition: config.h:115
config::uiPRules
aint uiPRules
the number of protected rule names found
Definition: config.h:118
vApiOutput
void vApiOutput(void *vpCtx, const char *cpOutput)
Generate a source and header file that can be used to construct a parser for the specified SABNF gram...
Definition: output.c:152
vMemDtor
void vMemDtor(void *vpCtx)
Destroys a Memory component. Frees all memory allocated.
Definition: memory.c:141
exception::try
abool try
True for the try block, false for the catch block.
Definition: exception.h:49
config::bDo
abool bDo
display the opcodes for each rule in human-readable form
Definition: config.h:129
vApiAttrsToAscii
void vApiAttrsToAscii(void *vpCtx, const char *cpMode, const char *cpFileName)
Display all rule attributes.
Definition: attributes.c:220
vApiPpptSize
void vApiPpptSize(void *vpCtx, pppt_size *spSize)
Compute the size of the PPPT maps and the number of bytes for the entire table.
Definition: pppt.c:246
config::cpDefaultConfig
char * cpDefaultConfig
if non-n=NULL, generate a default configuration file using this file name
Definition: config.h:108
config::uiInputFiles
aint uiInputFiles
the number of input files found
Definition: config.h:116
config
This data controls the flow of the main program of the APG parser generator.
Definition: config.h:106
config::bHelp
abool bHelp
the help flag, if set the help screen is printed and processing stops
Definition: config.h:119
vpApiCtor
void * vpApiCtor(exception *spEx)
Construct an API component context (object).
Definition: api.c:55
vUtilPrintMsgs
void vUtilPrintMsgs(void *vpMsgs)
Display the list of messages in a message object to stdout.
Definition: utilities.c:747
config::bDp
abool bDp
display the PPPT size
Definition: config.h:130
vApiInValidate
void vApiInValidate(void *vpCtx, abool bStrict)
Scans the input SABNF grammar for invalid characters and line ends.
Definition: input.c:204
config::bNoPppt
abool bNoPppt
if set, Partially-Predictive Parsing Tables (PPPTs) will not be produced
Definition: config.h:122
pppt_size::luiMapSize
luint luiMapSize
The size, in bytes, of a single PPPT table entry (map).
Definition: api.h:86
vConfigHelp
void vConfigHelp(void)
Prints the help screen when requested or if there is a command line options error.
Definition: config.c:210
vApiOpcodes
void vApiOpcodes(void *vpCtx)
Parse the SABNF grammar and translate its AST into opcodes for all the rules.
Definition: semantics.c:64
spConfigOptions
const config * spConfigOptions(void *vpCtx, int iArgCount, char **cppArgs)
Reads the command line arguments and parses them into a configuration structure.
Definition: config.c:194
vApiDtor
void vApiDtor(void *vpCtx)
The API component destructor.
Definition: api.c:84
vpApiGetErrorLog
void * vpApiGetErrorLog(void *vpCtx)
Get the internal message log.
Definition: api.c:117
pppt_size::luiAcharMax
luint luiAcharMax
The maximum character size in the grammar alphabet.
Definition: api.h:85
XTHROW
#define XTHROW(ctx, msg)
Exception throw macro.
Definition: exception.h:67
config::bDc
abool bDc
display the complete configuration as found on command line or configuration file
Definition: config.h:124
config::bStrict
abool bStrict
if set, the grammar is treated as strict ABNF
Definition: config.h:121
aint
uint_fast32_t aint
The APG parser's unsigned integer type.
Definition: apg.h:79
pppt_size::luiMaps
luint luiMaps
The number of maps needed.
Definition: api.h:87
main
int main(int argc, char **argv)
The executable from this main function is the ABNF Parser Generator application, APG.
Definition: main.c:61
config::cpLfOut
char * cpLfOut
if non-null, the file name for the converted LF line ends file
Definition: config.h:113
vConfigVersion
void vConfigVersion(void)
Display the version number.
Definition: config.c:266
config::cpGrammarHtml
char * cpGrammarHtml
if non-null, the file name for the HTML version of the annotated input grammar
Definition: config.h:111
vApiSyntax
void vApiSyntax(void *vpCtx, abool bStrict)
Parse the SABNF grammar to validate that the grammar structure is valid.
Definition: syntax.c:51
config::bDra
abool bDra
display the grammar rule/UDT names alphabetically
Definition: config.h:128
exception
A structure to describe the type and location of a caught exception.
Definition: exception.h:47
config::bDg
abool bDg
display an annotated version of the input grammar
Definition: config.h:125
pppt_size::luiTableSize
luint luiTableSize
The memory requirement, in bytes, of the full table.
Definition: api.h:88
config::cpCrLfOut
char * cpCrLfOut
if non-null, the file name for the converted CRLF line ends file
Definition: config.h:114
vApiRulesToAscii
void vApiRulesToAscii(void *vpCtx, const char *cpMode, const char *cpFileName)
Display rules and UDTs in human-readable format in ASCII format.
Definition: api.c:257
bApiAttrs
abool bApiAttrs(void *vpCtx)
Computes the grammar's attributes.
Definition: attributes.c:79
config::cppPRules
char ** cppPRules
array of protected rule names
Definition: config.h:117
pppt_size
Size information for the **P**artially-**P**redictive **P**arsing **T**ables (PPPT) data.
Definition: api.h:83
vpMemCtor
void * vpMemCtor(exception *spException)
Construct a memory component.
Definition: memory.c:121
cpApiInFile
const char * cpApiInFile(void *vpCtx, const char *cpFileName)
Reads an SABNF grammar byte stream from a file.
Definition: input.c:117
vConfigDisplay
void vConfigDisplay(const config *spConfig, int iArgCount, char **cppArgs)
Displays the full configuration as determined from the command line or command file arguments.
Definition: config.c:431
config::bDr
abool bDr
display grammar rule/UDT names in the order they occur in the grammar
Definition: config.h:127
pppt_size::luiAcharMin
luint luiAcharMin
The minimum character size in the grammar alphabet.
Definition: api.h:84
APG_TRUE
#define APG_TRUE
Definition: apg.h:291
config::bVersion
abool bVersion
the version flag, if set the version number is printed and processing stops
Definition: config.h:120
vApiAttrsErrorsToAscii
void vApiAttrsErrorsToAscii(void *vpCtx, const char *cpMode, const char *cpFileName)
Display all rule attributes with errors.
Definition: attributes.c:268
vApiInToAscii
void vApiInToAscii(void *vpCtx, const char *cpFileName)
Display the input lines with line numbers and character offsets.
Definition: input.c:261
vApiOpcodesToAscii
void vApiOpcodesToAscii(void *vpCtx, const char *cpFileName)
Display all opcodes in human-readable format.
Definition: api.c:328
APG_MAX_AINT
#define APG_MAX_AINT
Since the maximum unsigned integer value is used to indicate Infinite and Undefined values,...
Definition: apg.h:329
config.h
The configuration object header file.
vApiInToHtml
void vApiInToHtml(void *vpCtx, const char *cpFileName, const char *cpTitle)
Display the input lines with line numbers and character offsets.
Definition: input.c:319
vConfigDtor
void vConfigDtor(void *vpCtx)
The configuration destructor.
Definition: config.c:171
config::cpOutput
char * cpOutput
the path name for the generated C source & header files
Definition: config.h:110
vUtilConvertLineEnds
void vUtilConvertLineEnds(exception *spEx, const char *cpString, const char *cpEnd, const char *cpFileName)
Convert all line ending characters.
Definition: utilities.c:1228
config::bDa
abool bDa
display grammar attributes
Definition: config.h:126
vUtilPrintException
void vUtilPrintException(exception *spEx)
Prints exception information from an exception structure.
Definition: utilities.c:415
vpConfigCtor
void * vpConfigCtor(exception *spEx)
Constructs a configuration object to hold all data relating to this instance of the configuration.
Definition: config.c:97
vApiPppt
void vApiPppt(void *vpCtx, char **cppProtectedRules, aint uiProtectedRules)
Compute the Partially-Predictive Parsing Tables.
Definition: pppt.c:101
APG Version 7.0 is licensed under the 2-Clause BSD License,
an Open Source Initiative Approved License.