Browse Source

fix int and float constants to keep original text; print tokens properly; implement C_declaration; implement nested list building in the parser

master
Ian Piumarta 3 years ago
parent
commit
2cd0cbefaf
1 changed files with 190 additions and 128 deletions
  1. +190
    -128
      ccmeta.leg

+ 190
- 128
ccmeta.leg View File

@ -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-07-06 16:09:02 by piumarta on DESKTOP-LTPREOB
# Last edited: 2021-07-12 18:54:53 by piumarta on DESKTOP-LTPREOB
%{ %{
/* compile: leg -o ccmeta.c ccmeta.leg /* compile: leg -o ccmeta.c ccmeta.leg
@ -29,10 +29,11 @@
_DO(PostDecVariable) _DO(PostDecMember) _DO(PostDecIndex) \ _DO(PostDecVariable) _DO(PostDecMember) _DO(PostDecIndex) \
_DO(GetVariable) _DO(GetMember) _DO(SetMember) _DO(GetIndex) _DO(SetIndex) \ _DO(GetVariable) _DO(GetMember) _DO(SetMember) _DO(GetIndex) _DO(SetIndex) \
_DO(Return) _DO(Break) _DO(Continue) _DO(Throw) _DO(Try) \ _DO(Return) _DO(Break) _DO(Continue) _DO(Throw) _DO(Try) \
/* _DO(Quasiquote) _DO(Unquote) */ \
/* _DO(Quasiquote) _DO(Unquote) */ \
_DO(Comment) _DO(Token) \ _DO(Comment) _DO(Token) \
_DO(C_declaration) \
_DO(C_if) _DO(C_int) _DO(C_float) _DO(C_char) _DO(C_id) _DO(C_while) _DO(C_do) _DO(C_for) \ _DO(C_if) _DO(C_int) _DO(C_float) _DO(C_char) _DO(C_id) _DO(C_while) _DO(C_do) _DO(C_for) \
_DO(C_binary)
_DO(C_binary)
typedef enum { typedef enum {
t_UNDEFINED=0, t_UNDEFINED=0,
@ -85,7 +86,7 @@ oop globals= 0;
_DO(comment) \ _DO(comment) \
_DO(text) _DO(if) _DO(lparen) _DO(rparen) _DO(else) _DO(identifier) _DO(semicolon) _DO(while) \ _DO(text) _DO(if) _DO(lparen) _DO(rparen) _DO(else) _DO(identifier) _DO(semicolon) _DO(while) \
_DO(do) _DO(for) _DO(initExpr) _DO(condExpr) _DO(incrExpr) _DO(firstSemi) _DO(secondSemi) \ _DO(do) _DO(for) _DO(initExpr) _DO(condExpr) _DO(incrExpr) _DO(firstSemi) _DO(secondSemi) \
_DO(binary)
_DO(binary) _DO(specifiers) _DO(declarators)
#define _DO(NAME) oop NAME##_symbol; #define _DO(NAME) oop NAME##_symbol;
@ -259,29 +260,32 @@ oop new_C_if(oop ifTok, oop lParen, oop condition, oop rParen, oop consequent, o
return obj; return obj;
} }
oop new_C_while (oop whileTok, oop lParen, oop expression, oop rParen, oop statement) {
oop new_C_while(oop whileTok, oop lParen, oop expression, oop rParen, oop statement)
{
oop object = newObject(C_while_proto); oop object = newObject(C_while_proto);
map_set(object, while_symbol, whileTok);
map_set(object, lparen_symbol, lParen);
map_set(object, while_symbol, whileTok);
map_set(object, lparen_symbol, lParen);
map_set(object, expression_symbol, expression); map_set(object, expression_symbol, expression);
map_set(object, rparen_symbol, rParen); map_set(object, rparen_symbol, rParen);
map_set(object, statements_symbol, statement); map_set(object, statements_symbol, statement);
return object; return object;
} }
oop new_C_do (oop doTok, oop statement, oop whileTok, oop lParen, oop expression, oop rParen, oop semicolon) {
oop new_C_do(oop doTok, oop statement, oop whileTok, oop lParen, oop expression, oop rParen, oop semicolon)
{
oop object = newObject(C_do_proto); oop object = newObject(C_do_proto);
map_set(object, do_symbol, doTok); map_set(object, do_symbol, doTok);
map_set(object, statements_symbol, statement); map_set(object, statements_symbol, statement);
map_set(object, while_symbol, whileTok); map_set(object, while_symbol, whileTok);
map_set(object, lparen_symbol, lParen);
map_set(object, lparen_symbol, lParen);
map_set(object, expression_symbol, expression); map_set(object, expression_symbol, expression);
map_set(object, rparen_symbol, rParen); map_set(object, rparen_symbol, rParen);
map_set(object, semicolon_symbol, semicolon); map_set(object, semicolon_symbol, semicolon);
return object;
return object;
} }
oop new_C_for(oop forTok, oop lParen, oop initExpr, oop semicolon1, oop condExpr, oop semicolon2, oop incrExpr, oop rParen, oop statement) {
oop new_C_for(oop forTok, oop lParen, oop initExpr, oop semicolon1, oop condExpr, oop semicolon2, oop incrExpr, oop rParen, oop statement)
{
oop object = newObject(C_for_proto); oop object = newObject(C_for_proto);
map_set(object, for_symbol, forTok); map_set(object, for_symbol, forTok);
map_set(object, lparen_symbol, lParen); map_set(object, lparen_symbol, lParen);
@ -313,15 +317,15 @@ oop newSymbol(oop name)
return symbol; return symbol;
} }
oop new_C_int(int value) {
oop new_C_int(char *text) {
oop object = newObject(C_int_proto); oop object = newObject(C_int_proto);
map_set(object, value_symbol, makeInteger(value));
map_set(object, text_symbol, makeString(text));
return object; return object;
} }
oop new_C_float(float value) {
oop new_C_float(char *text) {
oop object = newObject(C_float_proto); oop object = newObject(C_float_proto);
map_set(object, value_symbol, makeFloat(value));
map_set(object, text_symbol, makeString(text));
return object; return object;
} }
@ -611,6 +615,19 @@ oop new_C_id(char* id) {
return object; return object;
} }
oop new_C_declaration(oop specifiers, oop declarators, oop semicolon) {
oop object = newObject(C_declaration_proto);
map_set(object, specifiers_symbol, specifiers);
map_set(object, declarators_symbol, declarators);
map_set(object, semicolon_symbol, semicolon);
return object;
}
void C_declarationBegin(void) {}
int C_declarationAbort(void) { return 0; }
void C_declarationEnd(void) {}
#define YY_INPUT(buf, result, max_size) \ #define YY_INPUT(buf, result, max_size) \
{ \ { \
@ -669,6 +686,40 @@ void setComment(oop ast, oop comment)
map_set(ast, comment_symbol, comment); map_set(ast, comment_symbol, comment);
} }
OopStack listOfLists= BUFFER_INITIALISER;
oop currentList= 0;
void listBegin(void)
{
OopStack_push(&listOfLists, currentList);
currentList= makeMap();
}
void listAppend(oop obj)
{
assert(currentList);
map_append(currentList, obj);
}
oop listEnd(void)
{
assert(currentList);
oop list= currentList;
currentList= OopStack_pop(&listOfLists);
return list;
}
oop listEmpty(void)
{
return makeMap();
}
void declarationTypedef(void)
{
printf("DECLARATION TYPEDEF\n");
}
%} %}
@ -680,7 +731,7 @@ error = EOL* < (!EOL .)* EOL* (!EOL .)* > &{ error(yytext), 1
# 6.4.2.1 # 6.4.2.1
idOpt = id #| TODO : End parsing | {$$=0}
idOpt = id #| TODO : End parsing | {$$=0}
id = <ID> { $$= new_C_id(yytext) } - id = <ID> { $$= new_C_id(yytext) } -
ID = <NAME> #| TODO : &{ !intern(yytext)->isKeyword } ID = <NAME> #| TODO : &{ !intern(yytext)->isKeyword }
@ -707,10 +758,10 @@ hexQuad = hexadecimalDigit hexadecimalDigit hexadecimalDigit hexadecimalDigit
# 6.4.4 # 6.4.4
constant = characterConstant
| floatingConstant
| integerConstant
constant = characterConstant
| floatingConstant
| integerConstant
# 6.4.4.1 # 6.4.4.1
@ -719,7 +770,7 @@ integerConstant = < ( hexadecimalConstant
| octalConstant | octalConstant
| binaryConstant &{gnu} | binaryConstant &{gnu}
| decimalConstant | decimalConstant
) integerSuffix? > { $$ = new_C_int(atoi(yytext)); } -
) integerSuffix? > { $$ = new_C_int(yytext); } -
decimalConstant = [1-9][0-9]* decimalConstant = [1-9][0-9]*
@ -741,7 +792,7 @@ imaginarySuffix = [ij]
# 6.4.4.2 # 6.4.4.2
floatingConstant = <( decimalFloatingConstant | hexadecimalFloatingConstant )> { $$ = new_C_float(atof(yytext)); } -
floatingConstant = <( decimalFloatingConstant | hexadecimalFloatingConstant )> { $$ = new_C_float(yytext); } -
decimalFloatingConstant = fractionalConstant exponentPart? floatingSuffix? decimalFloatingConstant = fractionalConstant exponentPart? floatingSuffix?
@ -769,7 +820,7 @@ floatingSuffix = [fFlL] imaginarySuffix?
# 6.4.4.4 # 6.4.4.4
characterConstant = < "'" cCharSequence "'" > { $$ = new_C_char(yytext) } - characterConstant = < "'" cCharSequence "'" > { $$ = new_C_char(yytext) } -
| < "L'" cCharSequence "'" > { $$ = new_C_char(yytext) } -
| < "L'" cCharSequence "'" > { $$ = new_C_char(yytext) } -
cCharSequence = ( escapeSequence | !EOL [^\'\\] )* cCharSequence = ( escapeSequence | !EOL [^\'\\] )*
@ -954,26 +1005,27 @@ hexadecimalEscapeSequence = '\\x' hexadecimalDigit+
#| #|
#|# 6.7 #|# 6.7
#| #|
#|declaration = @{ declarationBegin() }
#| ( s:declarationSpecifiers
#| d:initDeclaratorListOpt
#| t:SEMI { $$= newDeclaration(s, d, t) }
#| @{ declarationEnd() }
#| |
#| &{ declarationAbort() }
#| )
#|
#|declarationSpecifiers = @{ int specified= 0 } { listBegin() }
#| ( s:storageClassSpecifier { listAppend(s) }
#| | s:typeSpecifier @{ specified++ } { listAppend(s) }
#| | s:typedefName &{ !specified++ } { listAppend(s) }
#| | s:typeQualifier { listAppend(s) }
declaration = @{ C_declarationBegin() }
( s:declarationSpecifiers
d:initDeclaratorListOpt
t:SEMI { $$= new_C_declaration(s, d, t) }
@{ C_declarationEnd() }
|
&{ C_declarationAbort() }
)
declarationSpecifiers = @{ int specified= 0 } { listBegin() }
( s:storageClassSpecifier { listAppend(s) }
| s:typeSpecifier @{ specified++ } { listAppend(s) }
#| | s:typedefName &{ !specified++ } { listAppend(s) }
#| | s:typeQualifier { listAppend(s) }
#| | s:functionSpecifier { listAppend(s) } #| | s:functionSpecifier { listAppend(s) }
#| )+ { $$= listEnd() }
#| | &{gnu} { $$= 0 }
#|
)+ { $$= listEnd() }
| &{gnu} { $$= listEmpty() }
#|initDeclaratorListOpt = initDeclaratorList | { $$= 0 } #|initDeclaratorListOpt = initDeclaratorList | { $$= 0 }
#|
initDeclaratorListOpt = { $$= listEmpty() }
#|initDeclaratorList = d:initDeclarator { listWith(d) } #|initDeclaratorList = d:initDeclarator { listWith(d) }
#| ( c:COMMA d:initDeclarator { listAppend2(c, d) } #| ( c:COMMA d:initDeclarator { listAppend2(c, d) }
#| )* { $$= listEnd() } #| )* { $$= listEnd() }
@ -983,9 +1035,9 @@ hexadecimalEscapeSequence = '\\x' hexadecimalDigit+
#| )? { $$= d } #| )? { $$= d }
#| #|
#|# 6.7.1 #|# 6.7.1
#|
#|storageClassSpecifier = TYPEDEF @{ declarationTypedef() }
#| | AUTO
storageClassSpecifier = TYPEDEF @{ declarationTypedef() }
| AUTO
#| | parameterStorageClassSpecifier #| | parameterStorageClassSpecifier
#| | functionStorageClassSpecifier #| | functionStorageClassSpecifier
#| #|
@ -994,8 +1046,8 @@ hexadecimalEscapeSequence = '\\x' hexadecimalDigit+
#|functionStorageClassSpecifier = EXTERN | STATIC #|functionStorageClassSpecifier = EXTERN | STATIC
#| #|
#|# 6.7.2 #|# 6.7.2
#|
#|typeSpecifier = VOID | CHAR | SHORT | INT | LONG | FLOAT | DOUBLE | SIGNED | UNSIGNED | BOOL | COMPLEX
typeSpecifier = VOID | CHAR | SHORT | INT | LONG | FLOAT | DOUBLE | SIGNED | UNSIGNED | BOOL | COMPLEX
#| | structOrUnionSpecifier #| | structOrUnionSpecifier
#| | enumSpecifier #| | enumSpecifier
#| # Any list of specifiers and qualifiers at the start of a declaration may contain attribute specifiers #| # Any list of specifiers and qualifiers at the start of a declaration may contain attribute specifiers
@ -1269,9 +1321,8 @@ hexadecimalEscapeSequence = '\\x' hexadecimalDigit+
#| #|
externalDeclaration = <Space+> { yylval = newComment(yytext); } externalDeclaration = <Space+> { yylval = newComment(yytext); }
| ( SEMI &{gnu} | ( SEMI &{gnu}
| c:constant { yylval = c; } #| TODO
| i:idOpt { yylval = i; } #| TODO
#| | declaration
| c:constant { yylval = c; } #################| TODO
| declaration
#| | functionDefinition #| | functionDefinition
#| | meta #| | meta
| &. &{ errmsg= "declaration expected" } error | &. &{ errmsg= "declaration expected" } error
@ -2579,33 +2630,29 @@ void outputText(char *text)
ocol += strlen(text); ocol += strlen(text);
} }
void outputInt(int value) {
printf("%i", value);
char *toString = malloc(sizeof(value));
sprintf(toString,"%d", value);
ocol += strlen(toString);
void outputInt(int_t value)
{
ocol += printf(FMT_I, value);
} }
void outputFloat(float value) {
printf("%f", value);
char *toString = malloc(sizeof(value));
sprintf(toString,"%f", value);
ocol += strlen(toString);
void outputFloat(flt_t value)
{
ocol += printf(FMT_F, value);
} }
void outputNode(oop node) void outputNode(oop node)
{ {
if (!node) return; if (!node) return;
switch (node->type) {
case Undefined:
switch (getType(node)) {
case Undefined:
return; return;
case String:
outputText(get(node, String, value));
case String:
outputText(get(node, String, value));
return; return;
case Map:
case Map:
break; break;
case Integer:
outputInt(getInteger(node));
case Integer:
outputInt(getInteger(node));
return; return;
case Float: case Float:
outputFloat(getFloat(node)); outputFloat(getFloat(node));
@ -2614,74 +2661,89 @@ void outputNode(oop node)
outputText(get(node, Symbol, name)); outputText(get(node, Symbol, name));
return; return;
default: default:
fprintf(stderr, "\noutputNode: unknown node type %i\n", node->type);
fprintf(stderr, "\noutputNode: unknown node type %i\n", getType(node));
abort(); abort();
} }
assert(is(Map, node)); assert(is(Map, node));
oop proto= map_get(node, __proto___symbol); oop proto= map_get(node, __proto___symbol);
if (null == proto) return;
if (null == proto) { // assume this is just a list of nodes
size_t size= map_size(node);
for (size_t i= 0; i < size; ++i) {
if (!map_hasIntegerKey(node, i)) break;
outputNode(get(node, Map, elements)[i].value);
}
return;
}
// proto_number is the enum version of the proto symbol // proto_number is the enum version of the proto symbol
proto_t proto_number= get(map_get(proto, __name___symbol), Symbol, prototype); proto_t proto_number= get(map_get(proto, __name___symbol), Symbol, prototype);
switch (proto_number) { switch (proto_number) {
case t_Comment:
outputNode(map_get(node, text_symbol));
break;
case t_Token:
outputNode(map_get(node, name_symbol));
break;
case t_C_int:
outputNode(map_get(node, value_symbol));
break;
case t_C_float:
outputNode(map_get(node, value_symbol));
break;
case t_C_char:
outputNode(map_get(node, value_symbol));
break;
case t_C_id:
outputNode(map_get(node, identifier_symbol));
break;
case t_C_if:
outputNode(map_get(node, if_symbol));
outputNode(map_get(node, lparen_symbol));
outputNode(map_get(node, condition_symbol));
outputNode(map_get(node, rparen_symbol));
outputNode(map_get(node, consequent_symbol));
outputNode(map_get(node, else_symbol)); // null if no else clause
outputNode(map_get(node, alternate_symbol)); // null if no else clause
break;
case t_C_while:
outputNode(map_get(node, while_symbol));
outputNode(map_get(node, lparen_symbol));
outputNode(map_get(node, expression_symbol));
outputNode(map_get(node, rparen_symbol));
outputNode(map_get(node, statements_symbol));
break;
case t_C_do:
outputNode(map_get(node, do_symbol));
outputNode(map_get(node, statements_symbol));
outputNode(map_get(node, while_symbol));
outputNode(map_get(node, lparen_symbol));
outputNode(map_get(node, expression_symbol));
outputNode(map_get(node, rparen_symbol));
outputNode(map_get(node, semicolon_symbol));
break;
case t_C_for:
outputNode(map_get(node, for_symbol));
outputNode(map_get(node, lparen_symbol));
outputNode(map_get(node, initExpr_symbol));
outputNode(map_get(node, firstSemi_symbol));
outputNode(map_get(node, condExpr_symbol));
outputNode(map_get(node, secondSemi_symbol));
outputNode(map_get(node, incrExpr_symbol));
outputNode(map_get(node, rparen_symbol));
outputNode(map_get(node, statements_symbol));
break;
case t_C_binary:
outputNode(map_get(node, lhs_symbol));
outputNode(map_get(node, binary_symbol));
outputNode(map_get(node, rhs_symbol));
break;
case t_Comment:
outputNode(map_get(node, text_symbol));
break;
case t_Token:
outputNode(map_get(node, text_symbol));
break;
case t_C_int:
outputNode(map_get(node, text_symbol));
break;
case t_C_float:
outputNode(map_get(node, text_symbol));
break;
case t_C_char:
outputNode(map_get(node, value_symbol));
break;
case t_C_id:
outputNode(map_get(node, identifier_symbol));
break;
case t_C_declaration:
outputNode(map_get(node, specifiers_symbol));
outputNode(map_get(node, declarators_symbol));
outputNode(map_get(node, semicolon_symbol));
break;
case t_C_if:
outputNode(map_get(node, if_symbol));
outputNode(map_get(node, lparen_symbol));
outputNode(map_get(node, condition_symbol));
outputNode(map_get(node, rparen_symbol));
outputNode(map_get(node, consequent_symbol));
outputNode(map_get(node, else_symbol)); // null if no else clause
outputNode(map_get(node, alternate_symbol)); // null if no else clause
break;
case t_C_while:
outputNode(map_get(node, while_symbol));
outputNode(map_get(node, lparen_symbol));
outputNode(map_get(node, expression_symbol));
outputNode(map_get(node, rparen_symbol));
outputNode(map_get(node, statements_symbol));
break;
case t_C_do:
outputNode(map_get(node, do_symbol));
outputNode(map_get(node, statements_symbol));
outputNode(map_get(node, while_symbol));
outputNode(map_get(node, lparen_symbol));
outputNode(map_get(node, expression_symbol));
outputNode(map_get(node, rparen_symbol));
outputNode(map_get(node, semicolon_symbol));
break;
case t_C_for:
outputNode(map_get(node, for_symbol));
outputNode(map_get(node, lparen_symbol));
outputNode(map_get(node, initExpr_symbol));
outputNode(map_get(node, firstSemi_symbol));
outputNode(map_get(node, condExpr_symbol));
outputNode(map_get(node, secondSemi_symbol));
outputNode(map_get(node, incrExpr_symbol));
outputNode(map_get(node, rparen_symbol));
outputNode(map_get(node, statements_symbol));
break;
case t_C_binary:
outputNode(map_get(node, lhs_symbol));
outputNode(map_get(node, binary_symbol));
outputNode(map_get(node, rhs_symbol));
break;
default:
printf("I cannot print a node with proto_number %i\n", proto_number);
exit(0);
} }
#if 0 #if 0
while (orow < node->row) { printf("\n"); ++orow; ocol= 0; } while (orow < node->row) { printf("\n"); ++orow; ocol= 0; }

Loading…
Cancel
Save