diff --git a/ccmeta.leg b/ccmeta.leg index 2363758..7912538 100644 --- a/ccmeta.leg +++ b/ccmeta.leg @@ -39,7 +39,8 @@ _DO(C_sizeOf) _DO(C_cast) _DO(C_attributeSpec) _DO(C_asm) _DO(C_asmExpr) _DO(C_asmExprArg) \ _DO(C_aggregate) _DO(C_attribute) _DO(C_postfix) _DO(C_compound) _DO(C_functionDef) \ _DO(C_exprStatement) _DO(C_switch) _DO(C_goto) _DO(C_continue) _DO(C_break) _DO(C_return) \ - _DO(C_case) _DO(C_default) _DO(C_label) _DO(C_labelDeclaration) + _DO(C_case) _DO(C_default) _DO(C_label) _DO(C_labelDeclaration) _DO(C_structSpec) \ + _DO(C_structDeclarator) _DO(C_enumSpec) _DO(C_enum) typedef enum { t_UNDEFINED=0, @@ -98,8 +99,9 @@ oop globals= 0; _DO(primaryExpr) _DO(typeQualList) _DO(star) _DO(bxor) _DO(paramTypeL) _DO(assignExpr) \ _DO(static) _DO(dynamic) _DO(typeName) _DO(sizeOfTok) _DO(alignOfTok) _DO(llparen) _DO(lrparen) \ _DO(rlparen) _DO(rrparen) _DO(attributeL) _DO(attributeTok) _DO(typeOfTok) _DO(asmTok) _DO(element) \ - _DO(volatileTok) _DO(gotoTok) _DO(declarationL) _DO(compoundS) _DO(switchTok) _DO(continueTok) \ - _DO(breakTok) _DO(returnTok) _DO(caseTok) _DO(defaultTok) + _DO(volatileTok) _DO(gotoTok) _DO(declarationL) _DO(compoundS) _DO(switchTok) _DO(continueTok) \ + _DO(breakTok) _DO(returnTok) _DO(caseTok) _DO(defaultTok) _DO(attribute1) _DO(attribute2) \ + _DO(structTok) _DO(enumList) _DO(enumTok) #define _DO(NAME) oop NAME##_symbol; @@ -911,6 +913,43 @@ oop new_C_labelDeclaration(oop labelTok, oop list, oop semicolon) { return object; } +oop new_C_structSpec(oop structTok, oop attributeSpecifier1, oop id, oop leftCurly, oop declarationList, oop rightCurly, oop attributeSpecifier2) { + oop object = newObject(C_structSpec_proto); + map_set(object, structTok_symbol, structTok); + map_set(object, attribute1_symbol, attributeSpecifier1); + map_set(object, name_symbol, id); + map_set(object, leftCurly_symbol, leftCurly); + map_set(object, declarationL_symbol,declarationList); + map_set(object, rightCurly_symbol, rightCurly); + map_set(object, attribute2_symbol, attributeSpecifier2); + return object; +} + +oop new_C_structDeclarator(oop declarator, oop colon, oop expression) { + oop object = newObject(C_structDeclarator_proto); + map_set(object, declarators_symbol, declarator); + map_set(object, colon_symbol, colon); + map_set(object, expression_symbol, expression); + return object; +} + +oop new_C_enumSpec(oop enumTok, oop id, oop leftCurly, oop enumeratorList, oop rightCurly) { + oop object = newObject(C_enumSpec_proto); + map_set(object, enumTok_symbol, enumTok); + map_set(object, name_symbol, id); + map_set(object, leftCurly_symbol, leftCurly); + map_set(object, enumList_symbol, enumeratorList); + map_set(object, rightCurly_symbol, rightCurly); + return object; +} + +oop new_C_enumerator(oop id, oop attributeSpecifier, oop expression) { + oop object = newObject(C_enum_proto); + map_set(object, name_symbol, id); + map_set(object, attributeL_symbol, attributeSpecifier); + map_set(object, expression_symbol, expression); + return object; +} #define YY_INPUT(buf, result, max_size) \ { \ @@ -1324,7 +1363,6 @@ declarationSpecifiers = @{ int specified= 0 } { l | &{gnu} { $$= listEmpty() } initDeclaratorListOpt = initDeclaratorList | { $$= listEmpty() } -#|initDeclaratorListOpt = { $$= listEmpty() } initDeclaratorList = d:initDeclarator { listWith(d) } ( c:COMMA d:initDeclarator { listAppend2(c, d) } @@ -1348,39 +1386,39 @@ functionStorageClassSpecifier = EXTERN | STATIC # 6.7.2 typeSpecifier = VOID | CHAR | SHORT | INT | LONG | FLOAT | DOUBLE | SIGNED | UNSIGNED | BOOL | COMPLEX -#| | structOrUnionSpecifier -#| | enumSpecifier -#| # Any list of specifiers and qualifiers at the start of a declaration may contain attribute specifiers -#| | attributeSpecifier &{gnu} -#| -#|# 6.7.2.1 -#| -#|structOrUnionSpecifier = s:structOrUnion -#| # An attribute specifier list may appear as part of a struct, union or enum specifier. It may go -#| # either immediately after the struct, union or enum keyword... -#| ( a:attributeSpecifiers &{gnu} | {a=0} ) -#| ( i:idOpt ( @{ C_scopeBegin() } -#| l:LCURLY d:structDeclarationList r:RCURLY -#| @{ C_scopeEnd() } -#| | &{ C_scopeAbort() } -#| ) -#| # ..., or after the closing brace. -#| ( b:attributeSpecifiers &{gnu} | {b=0} ) -#| | i:id {l=d=r=b=0} -#| ) { $$= newStructSpec(s, a, i, l, d, r, b) } + | structOrUnionSpecifier + | enumSpecifier + # Any list of specifiers and qualifiers at the start of a declaration may contain attribute specifiers + | attributeSpecifier &{gnu} + +# 6.7.2.1 + +structOrUnionSpecifier = s:structOrUnion + # An attribute specifier list may appear as part of a struct, union or enum specifier. It may go + # either immediately after the struct, union or enum keyword... + ( a:attributeSpecifiers &{gnu} | {a=0} ) + ( i:idOpt ( @{ C_scopeBegin() } + l:LCURLY d:structDeclarationList r:RCURLY + @{ C_scopeEnd() } + | &{ C_scopeAbort() } + ) + # ..., or after the closing brace. + ( b:attributeSpecifiers &{gnu} | {b=0} ) + | i:id {l=d=r=b=0} + ) { $$= new_C_structSpec(s, a, i, l, d, r, b) } structOrUnion = STRUCT | UNION -#|structDeclarationList = d:structDeclaration { listWith(d) } -#| ( d:structDeclaration { listAppend(d) } -#| )* { $$= listEnd() } -#| | &{gnu} { $$= 0 } -#| -#|structDeclaration = s:specifierQualifierList d:structDeclaratorList t:SEMI -#| ( &SEMI { listWith(t) } -#| ( t:SEMI { listAppend(t) } -#| )* &{gnu} { t= listEnd() } -#| )? { $$= new_C_declaration(s, d, t) } +structDeclarationList = d:structDeclaration { listWith(d) } + ( d:structDeclaration { listAppend(d) } + )* { $$= listEnd() } + | &{gnu} { $$= 0 } + +structDeclaration = s:specifierQualifierList d:structDeclaratorList t:SEMI + ( &SEMI { listWith(t) } + ( t:SEMI { listAppend(t) } + )* &{gnu} { t= listEnd() } + )? { $$= new_C_declaration(s, d, t) } specifierQualifierList = @{ int specified= 0 } { listBegin() } ( ( t:typeSpecifier @{ specified++ } @@ -1389,38 +1427,38 @@ specifierQualifierList = @{ int specified= 0 } { listBegin() } ) { listAppend(t) } )+ { $$= listEnd() } -#|structDeclaratorList = d:structDeclarator { listWith(d) } -#| ( c:COMMA d:structDeclarator { listAppend2(c, d) } -#| )* { $$= listEnd() } -#| | &{gnu} { $$= 0 } -#| -#|structDeclarator = ( c:COLON e:constantExpression { d= newStructDeclarator(0, c, e) } -#| | d:declarator ( c:COLON e:constantExpression | {c=e=0} ) { d= newStructDeclarator(d, c, e) } -#| ) -#| # An attribute specifier list may appear immediately before the comma, = or semicolon terminating the declaration of an identifier -#| ( a:attributeSpecifiers { d= newAttribution(d, a) } -#| )? { $$= d } -#| -#|# 6.7.2.2 -#| -#|enumSpecifier = e:ENUM -#| ( i:idOpt l:LCURLY m:enumeratorList r:RCURLY { $$= newEnumSpec(e, i, l, m, r) } -#| | i:id { $$= newEnumSpec(e, i, 0, 0, 0) } -#| ) -#| -#|enumeratorList = e:enumerator { listWith(e) } -#| ( c:COMMA e:enumerator { listAppend(c); listAppend(e) } -#| )* -#| ( c:COMMA { listAppend(c) } -#| )? { $$= listEnd() } -#| -#|enumerator = i:id -#| # an attribute specifier list may appear as part of an enumerator. The attribute goes after the -#| # enumeration constant, before =, if present. -#| ( a:attributeSpecifier &{gnu} { i= newAttribution(i, a) } -#| )* -#| ( a:ASSIGN e:constantExpression | {a=e=0} ) { $$= newEnumerator(i, a, e) } -#| +structDeclaratorList = d:structDeclarator { listWith(d) } + ( c:COMMA d:structDeclarator { listAppend2(c, d) } + )* { $$= listEnd() } + | &{gnu} { $$= 0 } + +structDeclarator = ( c:COLON e:constantExpression { d= new_C_structDeclarator(0, c, e) } + | d:declarator ( c:COLON e:constantExpression | {c=e=0} ) { d= new_C_structDeclarator(d, c, e) } + ) + # An attribute specifier list may appear immediately before the comma, = or semicolon terminating the declaration of an identifier + ( a:attributeSpecifiers { d= new_C_attribution(d, a) } + )? { $$= d } + +# 6.7.2.2 + +enumSpecifier = e:ENUM + ( i:idOpt l:LCURLY m:enumeratorList r:RCURLY { $$= new_C_enumSpec(e, i, l, m, r) } + | i:id { $$= new_C_enumSpec(e, i, 0, 0, 0) } + ) + +enumeratorList = e:enumerator { listWith(e) } + ( c:COMMA e:enumerator { listAppend(c); listAppend(e) } + )* + ( c:COMMA { listAppend(c) } + )? { $$= listEnd() } + +enumerator = i:id + # an attribute specifier list may appear as part of an enumerator. The attribute goes after the + # enumeration constant, before =, if present. + ( a:attributeSpecifier &{gnu} { i= new_C_attribution(i, a) } + )* + ( a:ASSIGN e:constantExpression | {a=e=0} ) { $$= new_C_enumerator(i, a, e) } + # 6.7.3 typeQualifier = CONST | RESTRICT | VOLATILE @@ -1495,8 +1533,8 @@ identifierList = i:id { listWith(i) } ( c:COMMA i:id { listAppend2(c, i) } )* { $$= listEnd() } -#|# 6.7.6 -#| +# 6.7.6 + typeName = s:specifierQualifierList d:abstractDeclaratorOpt { $$= new_C_declaration(s, d, 0) } abstractDeclaratorOpt = abstractDeclarator | {$$=0} @@ -1614,11 +1652,11 @@ jumpStatement = g:GOTO i:id t:SEMI { $$= new_C_goto(g, 0, i, t) } | g:GOTO s:STAR x:expression t:SEMI &{gnu} { $$= new_C_goto(g, s, x, t) } ### A.2.4 External definitions -#| -#|# 6.9 -#| -#|translationUnit = externalDeclaration+ -#| + +# 6.9 + +translationUnit = externalDeclaration+ + externalDeclaration = { yylval = newComment(yytext); } | ( SEMI &{gnu} | c:constant { yylval = c; } #################| TODO @@ -3236,6 +3274,32 @@ void outputNode(oop node) outputNode(map_get(node, element_symbol)); outputNode(map_get(node, semicolon_symbol)); break; + case t_C_structSpec: + outputNode(map_get(node, structTok_symbol)); + outputNode(map_get(node, attribute1_symbol)); + outputNode(map_get(node, name_symbol)); + outputNode(map_get(node, leftCurly_symbol)); + outputNode(map_get(node, declarationL_symbol)); + outputNode(map_get(node, rightCurly_symbol)); + outputNode(map_get(node, attribute2_symbol)); + break; + case t_C_structDeclarator: + outputNode(map_get(node, declarators_symbol)); + outputNode(map_get(node, colon_symbol)); + outputNode(map_get(node, expression_symbol)); + break; + case t_C_enumSpec: + outputNode(map_get(node, enumTok_symbol)); + outputNode(map_get(node, name_symbol)); + outputNode(map_get(node, leftCurly_symbol)); + outputNode(map_get(node, enumList_symbol)); + outputNode(map_get(node, rightCurly_symbol)); + break; + case t_C_enum: + outputNode(map_get(node, name_symbol)); + outputNode(map_get(node, attributeL_symbol)); + outputNode(map_get(node, expression_symbol)); + break; default: printf("I cannot print a node with proto_number %i\n", proto_number); exit(0);