|
@ -3,7 +3,7 @@ |
|
|
# Copyright (c) 2016-2021 Ian Piumarta and other contributors (see AUTHORS) |
|
|
# Copyright (c) 2016-2021 Ian Piumarta and other contributors (see AUTHORS) |
|
|
# All rights reserved (see LICENSE) |
|
|
# All rights reserved (see LICENSE) |
|
|
# |
|
|
# |
|
|
# Last edited: 2021-08-16 18:55:57 by piumarta on DESKTOP-GMTB276 |
|
|
|
|
|
|
|
|
# Last edited: 2022-09-30 16:23:05 by piumarta on zora-10.local |
|
|
|
|
|
|
|
|
%{ |
|
|
%{ |
|
|
/* compile: leg -o ccmeta.c ccmeta.leg |
|
|
/* compile: leg -o ccmeta.c ccmeta.leg |
|
@ -54,22 +54,24 @@ DO_PROTOS() |
|
|
#undef _DO |
|
|
#undef _DO |
|
|
} proto_t; |
|
|
} proto_t; |
|
|
|
|
|
|
|
|
#define SYMBOL_PAYLOAD proto_t prototype; int is_C_keyword; |
|
|
|
|
|
|
|
|
#define SYMBOL_PAYLOAD proto_t prototype; |
|
|
#define DELTA 3 |
|
|
#define DELTA 3 |
|
|
|
|
|
|
|
|
#include "scope.c" |
|
|
#include "scope.c" |
|
|
#include "object.c" |
|
|
#include "object.c" |
|
|
|
|
|
|
|
|
#define DO_C_KEYWORDS() \ |
|
|
|
|
|
_DO(__alignof__) _DO(__alignof) _DO(asm) _DO(__asm) _DO(__asm__) _DO(__attribute__) _DO(auto) \ |
|
|
|
|
|
_DO(_Bool) _DO(break) _DO(case) _DO(char) _DO(_Complex) _DO(const) _DO(__const) _DO(continue) \ |
|
|
|
|
|
_DO(default) _DO(do) _DO(double) _DO(else) _DO(enum) _DO(extern) _DO(float) _DO(for) _DO(goto) \ |
|
|
|
|
|
_DO(if) _DO(inline) _DO(int) _DO(long) _DO(register) _DO(restrict) _DO(return) _DO(short) \ |
|
|
|
|
|
_DO(signed) _DO(sizeof) _DO(static) _DO(struct) _DO(switch) _DO(typedef) _DO(typeof) \ |
|
|
|
|
|
_DO(__typeof__) _DO(union) _DO(unsigned) _DO(void) _DO(volatile) _DO(while) |
|
|
|
|
|
|
|
|
// these MUST be in alphabetical order otherwise keywords will not be identified |
|
|
|
|
|
#define DO_C_KEYWORDS() \ |
|
|
|
|
|
_DO(_Bool) _DO(_Complex) _DO(__alignof) _DO(__alignof__) _DO(__asm) _DO(__asm__) _DO(__attribute__) _DO(__const) \ |
|
|
|
|
|
_DO(__typeof__) _DO(asm) _DO(auto) _DO(break) _DO(case) _DO(char) _DO(const) _DO(continue) \ |
|
|
|
|
|
_DO(default) _DO(do) _DO(double) _DO(else) _DO(enum) _DO(extern) _DO(float) _DO(for) \ |
|
|
|
|
|
_DO(goto) _DO(if) _DO(inline) _DO(int) _DO(long) _DO(register) _DO(restrict) _DO(return) \ |
|
|
|
|
|
_DO(short) _DO(signed) _DO(sizeof) _DO(static) _DO(struct) _DO(switch) _DO(typedef) _DO(typeof) \ |
|
|
|
|
|
_DO(union) _DO(unsigned) _DO(void) _DO(volatile) _DO(while) |
|
|
|
|
|
|
|
|
#define DO_C_KEYWORDS_GNU() \ |
|
|
|
|
|
_DO(__complex__) _DO(__inline__) _DO(__imag__) _DO(__label__) _DO(__real__) |
|
|
|
|
|
|
|
|
// these MUST be in alphabetical order otherwise keywords will not be identified |
|
|
|
|
|
#define DO_GNU_KEYWORDS() \ |
|
|
|
|
|
_DO(__complex__) _DO(__imag__) _DO(__inline__) _DO(__label__) _DO(__real__) |
|
|
|
|
|
|
|
|
#include <setjmp.h> |
|
|
#include <setjmp.h> |
|
|
|
|
|
|
|
@ -668,10 +670,9 @@ void listWith(oop obj) { |
|
|
|
|
|
|
|
|
oop listEnd(void) |
|
|
oop listEnd(void) |
|
|
{ |
|
|
{ |
|
|
if(isEmpty) return null; |
|
|
|
|
|
assert(currentList); |
|
|
|
|
|
oop list= currentList; |
|
|
|
|
|
|
|
|
oop list= currentList; assert(list); |
|
|
currentList= OopStack_pop(&listOfLists); |
|
|
currentList= OopStack_pop(&listOfLists); |
|
|
|
|
|
if (isEmpty) return null; |
|
|
return list; |
|
|
return list; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -898,6 +899,42 @@ void error(char *source) |
|
|
exit(1); |
|
|
exit(1); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int isKeyword(char *word, char **keywords, ssize_t n) |
|
|
|
|
|
{ |
|
|
|
|
|
ssize_t lo = 0, hi = n - 1; |
|
|
|
|
|
while (lo <= hi) { |
|
|
|
|
|
ssize_t mi = (lo + hi) / 2; |
|
|
|
|
|
char *key = keywords[mi]; |
|
|
|
|
|
int cmp = strcmp(key, word); |
|
|
|
|
|
if (cmp < 0) lo = mi + 1; |
|
|
|
|
|
else if (cmp > 0) hi = mi - 1; |
|
|
|
|
|
else return 1; |
|
|
|
|
|
} |
|
|
|
|
|
return 0; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#define indexableSize(A) (sizeof(A) / sizeof(*(A))) |
|
|
|
|
|
|
|
|
|
|
|
int is_GNU_keyword(char *word) |
|
|
|
|
|
{ |
|
|
|
|
|
char *keywords[] = { |
|
|
|
|
|
#define _DO(W) #W, |
|
|
|
|
|
DO_GNU_KEYWORDS() |
|
|
|
|
|
#undef _DO |
|
|
|
|
|
}; |
|
|
|
|
|
return isKeyword(word, keywords, indexableSize(keywords)); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int is_C_keyword(char *word) |
|
|
|
|
|
{ |
|
|
|
|
|
char *keywords[] = { |
|
|
|
|
|
#define _DO(W) #W, |
|
|
|
|
|
DO_C_KEYWORDS() |
|
|
|
|
|
#undef _DO |
|
|
|
|
|
}; |
|
|
|
|
|
return isKeyword(word, keywords, indexableSize(keywords)); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
#define newBegin() newToken("{") |
|
|
#define newBegin() newToken("{") |
|
|
#define newEnd() newToken("}") |
|
|
#define newEnd() newToken("}") |
|
|
|
|
|
|
|
@ -1283,7 +1320,7 @@ error = EOL* < (!EOL .)* EOL* (!EOL .)* > &{ error(yytext), 1 |
|
|
idOpt = id | {$$=newNullObject()} |
|
|
idOpt = id | {$$=newNullObject()} |
|
|
|
|
|
|
|
|
id = <ID> { $$= new_C_id(yytext) } - |
|
|
id = <ID> { $$= new_C_id(yytext) } - |
|
|
ID = <NAME> &{ !get(intern(yytext), Symbol, is_C_keyword) } |
|
|
|
|
|
|
|
|
ID = <NAME> &{ !is_C_keyword(yytext) } |
|
|
|
|
|
|
|
|
name = <NAME> { $$= new_C_id(yytext) } - |
|
|
name = <NAME> { $$= new_C_id(yytext) } - |
|
|
NAME = IDFIRST IDREST* |
|
|
NAME = IDFIRST IDREST* |
|
@ -2098,7 +2135,7 @@ __INLINE = '__inline' !IDREST &{gnu} { $$= newToken("__inlin |
|
|
_FLOAT128 = '_Float128' !IDREST &{gnu} { $$= newToken("_Float128" ) } - |
|
|
_FLOAT128 = '_Float128' !IDREST &{gnu} { $$= newToken("_Float128" ) } - |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#--------------------------------------------- Common rules ----------------------------------------------# |
|
|
|
|
|
|
|
|
#--------------------------------------------- Common rules ----------------------------------------------# |
|
|
|
|
|
|
|
|
- = (blank | comment)* &{lang == META} |
|
|
- = (blank | comment)* &{lang == META} |
|
|
| < Space* > &{lang == C} { if (yyleng && $$) setComment($$, newComment(yytext)) } |
|
|
| < Space* > &{lang == C} { if (yyleng && $$) setComment($$, newComment(yytext)) } |
|
@ -2121,13 +2158,13 @@ Directive = "#" (!EOL .)* |
|
|
Any = . { ++icol } |
|
|
Any = . { ++icol } |
|
|
|
|
|
|
|
|
#| Meta rules |
|
|
#| Meta rules |
|
|
blank = space | eol |
|
|
|
|
|
space = [ \t] |
|
|
|
|
|
eol = ( "\n""\r"* |
|
|
|
|
|
| "\r""\n"* |
|
|
|
|
|
) { inputStack->lineNumber++ } |
|
|
|
|
|
|
|
|
blank = space | eol |
|
|
|
|
|
space = [ \t] |
|
|
|
|
|
eol = ( "\n""\r"* |
|
|
|
|
|
| "\r""\n"* |
|
|
|
|
|
) { inputStack->lineNumber++ } |
|
|
|
|
|
|
|
|
comment = "//" ( ![\n\r] . )* |
|
|
|
|
|
|
|
|
comment = "//" ( ![\n\r] . )* |
|
|
| "/*" ( !"*/" (eol | .) )* "*/" |
|
|
| "/*" ( !"*/" (eol | .) )* "*/" |
|
|
|
|
|
|
|
|
#--------------------------------------------- Meta grammar ----------------------------------------------# |
|
|
#--------------------------------------------- Meta grammar ----------------------------------------------# |
|
@ -4259,7 +4296,7 @@ void outputTree(oop node, int depth) |
|
|
break; |
|
|
break; |
|
|
#undef CASE |
|
|
#undef CASE |
|
|
|
|
|
|
|
|
/** Meta nodes */ |
|
|
|
|
|
|
|
|
/** Meta nodes */ |
|
|
|
|
|
|
|
|
#define CASE(NAME) case t_##NAME:printf("%s:\n", #NAME); |
|
|
#define CASE(NAME) case t_##NAME:printf("%s:\n", #NAME); |
|
|
CASE(Map) |
|
|
CASE(Map) |
|
@ -4334,7 +4371,7 @@ void outputTree(oop node, int depth) |
|
|
CASE(Logand) |
|
|
CASE(Logand) |
|
|
OUT(lhs); |
|
|
OUT(lhs); |
|
|
OUT(rhs); |
|
|
OUT(rhs); |
|
|
break; |
|
|
|
|
|
|
|
|
break; |
|
|
CASE(Continue) |
|
|
CASE(Continue) |
|
|
break; |
|
|
break; |
|
|
CASE(Bitand) |
|
|
CASE(Bitand) |
|
@ -4559,13 +4596,6 @@ int main(int argc, char **argv) |
|
|
/* File scope */ |
|
|
/* File scope */ |
|
|
pushScope(); |
|
|
pushScope(); |
|
|
|
|
|
|
|
|
#define _DO(NAME) set(intern(#NAME), Symbol, is_C_keyword, 1); |
|
|
|
|
|
DO_C_KEYWORDS() |
|
|
|
|
|
if(gnu) { |
|
|
|
|
|
DO_C_KEYWORDS_GNU(); |
|
|
|
|
|
} |
|
|
|
|
|
#undef _DO |
|
|
|
|
|
|
|
|
|
|
|
int repled = 0; |
|
|
int repled = 0; |
|
|
/* Checking arguments */ |
|
|
/* Checking arguments */ |
|
|
while (argc-- > 1) { |
|
|
while (argc-- > 1) { |
|
|