25 #include "Generator.h"
26 #include "SABNFGrammar.h"
32 void* g_vpErrCtx = NULL;
33 void* g_vpWarnCtx = NULL;
35 static G_UINT uiValidateGrammar(
void* vpCatCtx,
void* vpErrCtx,
void* vpWarnCtx);
115 int main(
int argc,
char** argv){
116 int iReturn = EXIT_FAILURE;
117 void* vpMemCtx = NULL;
118 void* vpParserCtx = NULL;
119 void* vpCatCtx = NULL;
120 void* vpErrCtx = NULL;
121 void* vpWarnCtx = NULL;
122 char* cpInputString = NULL;
126 G_UINT uiInputStringLen = 0;
127 G_UINT uiInputStringBufLen = 0;
129 CALLBACK_CTX sCallbackCtx;
130 GRAMMAR_METRICS sMetrics;
140 MSGASSERT(vpMemCtx,
"memory component constructor failed");
141 vpErrCtx = vpErrorsCtor(vpMemCtx, vMainAlertHandler);
142 MSGASSERT(vpErrCtx,
"error reporting constructor failed");
143 g_vpErrCtx = vpErrCtx;
144 vpWarnCtx = vpErrorsCtor(vpMemCtx, vMainAlertHandler);
145 MSGASSERT(vpWarnCtx,
"warning reporting component constructor failed");
146 g_vpWarnCtx = vpWarnCtx;
152 uiTest = uiCommandLine(&sConfig, argc, argv);
158 printf(
"%s - output redirect file\n", sConfig.caLog);
159 spRedirectOut = freopen(sConfig.caLog,
"w", stdout);
160 MSGASSERT(spRedirectOut,
"failed to open output redirect file");
162 if(sConfig.uiVersion){
167 vDisplayHelp(argc, argv);
170 if(!sConfig.uiInput){
172 printf(
"input file name is required\n");
173 vDisplayHelp(argc, argv);
177 if(sConfig.uiDisplayConfig){
179 printf(
"configuration parameters\n");
180 vDisplayConfig(&sConfig);
182 if(sConfig.uiDisplayTypes){
184 printf(
"integer type sizes\n");
193 MSGASSERT(uiInputStringLen,
"failed to get input file size - file probably does not exist");
194 uiInputStringBufLen = (
sizeof(
apg_achar) * 2) * (uiInputStringLen + 10);
195 cpInputString = (
char*)
vpMemAlloc(vpMemCtx, uiInputStringBufLen);
196 MSGASSERT(cpInputString,
"failed to allocate memory for input string");
197 uiTest =
uiGetFile(&sConfig.caInput[0], (
void*)cpInputString);
198 MSGASSERT(uiTest,
"failed to read input string");
199 if(!((cpInputString[uiInputStringLen - 1] == (
char)10) || (cpInputString[uiInputStringLen - 1] == (
char)13))){
200 vErrorsReport(vpWarnCtx,
"Grammar: Last line has no line ending. Line end CRLF added.");
201 cpInputString[uiInputStringLen] = (char)13;
203 cpInputString[uiInputStringLen] = (char)10;
206 cpInputString[uiInputStringLen] = 0;
208 vpCatCtx = vpCatalogCtor(vpMemCtx, vMainAlertHandler);
209 MSGASSERT(vpCatCtx,
"line number catalog constructor failed");
210 uiTest = uiCatalogLines(vpCatCtx, cpInputString, uiInputStringLen);
211 if(cpInputString && uiInputStringLen && sConfig.uiDisplayGrammar){
213 printf(
"annotated input string\n");
214 vCatalogDisplay(vpCatCtx, stdout);
216 MSGASSERT(uiTest,
"line number cataloging failed");
218 uiTest = uiValidateGrammar(vpCatCtx, vpErrCtx, vpWarnCtx);
219 MSGASSERT(uiTest,
"grammar validation failed");
222 MSGASSERT(acpInputString,
"failed to allocate memory for alphabet character translation of input string");
223 vCharToAChar(acpInputString, cpInputString, uiInputStringLen);
229 vpParserCtx =
vpParserCtor(vpParserInit_SABNFGrammar, vMainAlertHandler);
230 MSGASSERT(vpParserCtx,
"parser constructor failed");
231 vSemanticInit(saSemantic);
235 vCallbackInit(vpMemCtx, &sCallbackCtx);
236 sCallbackCtx.pfnAlertHandler = vMainAlertHandler;
237 sCallbackCtx.vpErrCtx = vpErrCtx;
238 sCallbackCtx.vpWarnCtx = vpWarnCtx;
239 sCallbackCtx.vpLineCatalogCtx = vpCatCtx;
240 uiTest =
uiParserSyntaxAnalysis(vpParserCtx, RULE_SABNFGRAMMAR_FILE, acpInputString, uiInputStringLen, &sCallbackCtx);
241 MSGASSERT(uiTest,
"parser syntax analysis failed");
242 if(sConfig.uiDisplayState){
244 printf(
"generator state\n");
247 if(sConfig.uiDisplayAst){
252 if(uiErrorsCount(vpErrCtx)){
260 if(uiErrorsCount(vpErrCtx)){
break;}
261 if(sConfig.uiDisplayGrammarMetrics){
264 printf(
"grammar metrics\n");
265 vGrammarMetrics(&sCallbackCtx, &sMetrics);
266 vDisplayGrammarMetrics(&sMetrics);
268 if(sConfig.uiDisplayRules){
272 vGeneratorDisplayRules(&sCallbackCtx);
274 if(sConfig.uiDisplayOpcodes){
277 printf(
"opcodes (in human-readable format)n");
278 vGeneratorDisplayOpcodes(&sCallbackCtx);
285 ATTRS_CTX* vpAttrsCtx = (ATTRS_CTX*)vpAttrsCtor(&sCallbackCtx);
286 MSGASSERT(vpAttrsCtx,
"attributes component constructor failed");
287 uiTest = uiAttributes(vpAttrsCtx);
289 if(sConfig.uiDisplayAttributes){
291 printf(
"rule reference types\n");
292 vDisplayRuleDependencyTypes(vpAttrsCtx);
294 printf(
"grammar attributes\n");
295 vDisplayAttrs(vpAttrsCtx);
298 vErrorsReport(vpErrCtx,
"Attributes error: unparsable attributes found - displaying attributes");
300 printf(
"rule reference types\n");
301 vDisplayRuleDependencyTypes(vpAttrsCtx);
303 printf(
"grammar attributes\n");
304 vDisplayAttrs(vpAttrsCtx);
313 char caFileName[1024];
315 if(sConfig.uiOutput){cpPath = &sConfig.caOutput[0];}
317 printf(
"C parser generated\n");
318 vGenerateCHeader(&sCallbackCtx, cpPath, &sConfig.caC[0], cpInputString, caFileName, 1024);
319 printf(
" %s\n", caFileName);
320 vGenerateCSource(&sCallbackCtx, cpPath, &sConfig.caC[0], caFileName, 1024);
321 printf(
" %s\n", caFileName);
325 char caFileName[1024];
327 if(sConfig.uiOutput){cpPath = &sConfig.caOutput[0];}
329 printf(
"C++ parser generated\n");
330 vGenerateCppHeader(&sCallbackCtx, cpPath, &sConfig.caCpp[0], cpInputString, caFileName, 1024);
331 printf(
" %s\n", caFileName);
332 vGenerateCppSource(&sCallbackCtx, cpPath, &sConfig.caCpp[0], caFileName, 1024);
333 printf(
" %s\n", caFileName);
336 if(!uiTrace){printf(
"<no parser output requested>\n");}
339 iReturn = EXIT_SUCCESS;
345 if(sConfig.uiDisplayWarnings && vpWarnCtx && (G_UINT)uiErrorsCount(vpWarnCtx)){
347 printf(
"%lu warning(s) detected\n", (
printf_uint)uiErrorsCount(vpWarnCtx));
348 char* cpMsg = cpErrorsIterInit(vpWarnCtx);
351 printf(
"%lu: %s\n", (G_UINT)uiError, cpMsg);
353 cpMsg = cpErrorsIterNext(vpWarnCtx);
356 if(vpErrCtx && uiErrorsCount(vpErrCtx)){
358 printf(
"%lu error(s) detected\n", (
printf_uint)uiErrorsCount(vpErrCtx));
359 char* cpMsg = cpErrorsIterInit(vpErrCtx);
362 printf(
"%lu: %s\n", (G_UINT)uiError, cpMsg);
364 cpMsg = cpErrorsIterNext(vpErrCtx);
373 static G_UINT uiValidateGrammar(
void* vpCatCtx,
void* vpErrCtx,
void* vpWarnCtx){
375 CATALOG_CTX* spCtx = (CATALOG_CTX*)vpCatCtx;
376 CATALOG_LINE* spLine = NULL;
377 unsigned char* ucpChar;
380 char caBuffer[2 * MAX_DISPLAY_LINE_LEN + 10];
382 spLine = spCatalogIterInit(vpCatCtx);
384 if(spLine->uiLineEndLen == 1){uiHasNonABNFLineEnd =
APG_TRUE;}
386 for(ucpChar = (
unsigned char*)spLine->cpBeg; ucpChar < (
unsigned char*)spLine->cpEnd; ucpChar++, uiChar++){
388 if(*ucpChar < (
unsigned char)9){uiError =
APG_TRUE;}
389 else if(*ucpChar > (
unsigned char)10 && *ucpChar < (
unsigned char)13){uiError =
APG_TRUE;}
390 else if(*ucpChar > (
unsigned char)13 && *ucpChar < (
unsigned char)32){uiError =
APG_TRUE;}
391 else if(*ucpChar > (
unsigned char)127){uiError =
APG_TRUE;}
396 n += sprintf(&caBuffer[n],
397 "Grammar: invalid character: line no: %lu: character no: %lu: character: %lu\n ",
398 (G_UINT)spLine->uiLineNo, (G_UINT)(spLine->uiBegChar + uiChar), (G_UINT)*ucpChar);
399 vCatalogDisplayLine(spLine, &caBuffer[n], MAX_DISPLAY_LINE_LEN);
400 vErrorsReport(vpErrCtx, &caBuffer[0]);
403 spLine = spCatalogIterNext(vpCatCtx);
406 if(uiHasNonABNFLineEnd){
407 vErrorsReport(vpWarnCtx,
"Grammar: has non-ABNF(non-CRLF) line endings");
413 void vMainAlertHandler(
unsigned int uiLine,
const char* cpFile){
415 printf(
"ERROR: an unrecoverable error was encountered at the following file and line number:\n");
416 printf(
" line: %lu\n", (G_UINT)uiLine);
417 printf(
" file: %s\n", cpFile);
419 if(g_vpErrCtx && uiErrorsCount(g_vpErrCtx)){
420 char* cpMsg = cpErrorsIterInit(g_vpErrCtx);
423 printf(
"\n*** %lu error(s) reported to the error log ***\n", (G_UINT)uiErrorsCount(g_vpErrCtx));
425 printf(
"%lu: %s\n", (G_UINT)uiError, cpMsg);
427 cpMsg = cpErrorsIterNext(g_vpErrCtx);
431 if(g_vpWarnCtx && uiErrorsCount(g_vpWarnCtx)){
432 char* cpMsg = cpErrorsIterInit(g_vpWarnCtx);
435 printf(
"\n*** %lu warning(s) reported to the warning log ***\n", (G_UINT)uiErrorsCount(g_vpWarnCtx));
437 printf(
"%lu: %s\n", (G_UINT)uiError, cpMsg);
439 cpMsg = cpErrorsIterNext(g_vpWarnCtx);
444 printf(
"*** exit(EXIT_FAILURE) called ***\n");
448 void vMsgAssert(
char* cpMsg,
unsigned int uiLine,
char* cpFile){
449 char caAssertBuffer[4096];
450 char* cpAssertBuffer = &caAssertBuffer[0];
452 char* cpNoMsg =
"<no message>";
453 if(!cpMsg){cpMsg = cpNoMsg;}
454 uiLen = strlen(cpMsg);
455 if(!uiLen){cpMsg = cpNoMsg;}
456 sprintf(cpAssertBuffer,
"line: %lu: file: %s: msg: %s", (G_UINT)uiLine, cpFile, cpMsg);
457 vErrorsReport(g_vpErrCtx, cpAssertBuffer);
458 vMainAlertHandler(uiLine, cpFile);