From e0d3e12df67807e18c589a1c7245aa9909d267bb Mon Sep 17 00:00:00 2001 From: theo <2022xmm3@kuas.ac.jp> Date: Thu, 13 Oct 2022 16:19:26 +0900 Subject: [PATCH] Reorganising and adding rules to the file Added rules ideas for interpreting the following expressions: @(a = `constant 10) int q = @(`constant 10); int w = @(a); --- ccmeta.leg | 1727 +++++++++++++++++++++++++++------------------------- 1 file changed, 881 insertions(+), 846 deletions(-) diff --git a/ccmeta.leg b/ccmeta.leg index 647bf85..2967300 100644 --- a/ccmeta.leg +++ b/ccmeta.leg @@ -6,10 +6,10 @@ # Last edited: 2022-09-30 16:23:05 by piumarta on zora-10.local %{ -/* compile: leg -o ccmeta.c ccmeta.leg - * cc -o ccmeta ccmeta.c -lgc -lm +/* compile: leg -o ccmeta.c ccmeta.leg + * cc -o ccmeta ccmeta.c -lgc -lm * - * run: ./ccmeta < ccmeta-test.txt + * run: ./ccmeta < ccmeta-test.txt */ #include @@ -29,7 +29,7 @@ _DO(PostDecVariable) _DO(PostDecMember) _DO(PostDecIndex) \ _DO(GetVariable) _DO(GetMember) _DO(SetMember) _DO(GetIndex) _DO(SetIndex) \ _DO(Return) _DO(Break) _DO(Continue) _DO(Throw) _DO(Try) \ - /* _DO(Quasiquote) _DO(Unquote) */ \ + /* _DO(Quasiquote) _DO(Unquote) */ \ DO_C_PROTOS() #define META_PROTO_MAX t_Try @@ -91,13 +91,13 @@ typedef struct jb_record jb_record *jbs= NULL; -#define jbRecPush() \ - struct jb_record jbrec; \ - jbrec.next= jbs; \ +#define jbRecPush() \ + struct jb_record jbrec; \ + jbrec.next= jbs; \ jbs= &jbrec -#define jbRecPop() \ - assert(jbs == &jbrec); \ +#define jbRecPop() \ + assert(jbs == &jbrec); \ jbs= jbrec.next // this is the global scope @@ -110,7 +110,7 @@ oop globals= 0; _DO(update) _DO(this) _DO(fixed) _DO(operator) _DO(map) _DO(func) \ _DO(try) _DO(catch) _DO(finally) _DO(exception) \ _DO(__line__) _DO(__file__) \ - _DO(comment) \ + _DO(comment) \ _DO(text) _DO(ifTok) _DO(lparen) _DO(rparen) _DO(elseTok) _DO(identifier) _DO(semicolon) \ _DO(whileTok) \ _DO(doTok) _DO(forTok) _DO(initExpr) _DO(condExpr) _DO(incrExpr) _DO(firstSemi) _DO(secondSemi) \ @@ -228,9 +228,9 @@ oop getVariable(oop object, oop key) while (!map_hasKey(object, key)) { object = map_get(object, __proto___symbol); if (null == object) { - if (key == __proto___symbol) + if (key == __proto___symbol) return getVariable(globals, Map_symbol); - runtimeError("Undefined: %s", printString(key)); + runtimeError("Undefined: %s", printString(key)); } } return map_get(object, key); @@ -241,7 +241,7 @@ oop getMember(oop object, oop key) while (!map_hasKey(object, key)) { object = map_get(object, __proto___symbol); if (null == object) { - return null; + return null; } } return map_get(object, key); @@ -670,7 +670,7 @@ void listWith(oop obj) { oop listEnd(void) { - oop list= currentList; assert(list); + oop list= currentList; assert(list); currentList= OopStack_pop(&listOfLists); if (isEmpty) return null; return list; @@ -913,7 +913,7 @@ int isKeyword(char *word, char **keywords, ssize_t n) return 0; } -#define indexableSize(A) (sizeof(A) / sizeof(*(A))) +#define indexableSize(A) (sizeof(A) / sizeof(*(A))) int is_GNU_keyword(char *word) { @@ -935,8 +935,8 @@ int is_C_keyword(char *word) return isKeyword(word, keywords, indexableSize(keywords)); } -#define newBegin() newToken("{") -#define newEnd() newToken("}") +#define newBegin() newToken("{") +#define newEnd() newToken("}") oop newToken(char *text) { @@ -975,7 +975,7 @@ oop setVariable(oop object, oop key, oop value) oop getProperty(oop object, oop key) { if (!map_hasKey(object, key)) { - runtimeError("Undefined: .%s", printString(key)); + runtimeError("Undefined: .%s", printString(key)); } return map_get(object, key); } @@ -1293,6 +1293,12 @@ typedef enum { language lang = C, printLang = C; +// Part of creation of meta object for C + + void createMetaInteger() { + + } + %} @@ -1301,42 +1307,36 @@ language lang = C, printLang = C; # yylval == null => "pseudo" op, e.g., change language -- ignored by REPL # yylval == 0 => end of input file while in META mode only -start = m:mexp { yylval= m } - | META_AT META_LCB { yylval= null; lang= META } - | &{ lang == META } - s:meta { yylval= s } - | &{ lang == META } - META_RCB { yylval= null; lang= C } - | &{ lang == C } s:externalDeclaration { yylval= s } +start = m:metaCatch { yylval = m } + | s:externalDeclaration { yylval= s } -mexp = META_AT META_LPAREN ( @{ lang = META } s:meta_exp META_RPAREN @{ lang = C } { $$= s } - | @{ lang = C } &{ 0 } - ) - -error = EOL* < (!EOL .)* EOL* (!EOL .)* > &{ error(yytext), 1 } +error = EOL* < (!EOL .)* EOL* (!EOL .)* > &{ error(yytext), 1 } ### A.1.3 Identifiers # 6.4.2.1 -idOpt = id | {$$=newNullObject()} +idOpt = id | {$$=newNullObject()} -id = { $$= new_C_id(yytext) } - -ID = &{ !is_C_keyword(yytext) } +id = { $$= new_C_id(yytext) } - +ID = &{ !is_C_keyword(yytext) } -name = { $$= new_C_id(yytext) } - -NAME = IDFIRST IDREST* +name = { $$= new_C_id(yytext) } - +NAME = IDFIRST IDREST* -IDFIRST = [a-zA-Z_] | universalCharacterName | '$' &{gnu} -IDREST = IDFIRST | [0-9] +IDFIRST = [a-zA-Z_] | universalCharacterName | '$' &{gnu} +IDREST = IDFIRST | [0-9] -digit = [0-9] +digit = [0-9] ### A.1.4 Universal character names # 6.4.3 -universalCharacterName = "\\u" hexQuad | "\\U" hexQuad hexQuad +universalCharacterName = "\\u" hexQuad + | "\\U" hexQuad hexQuad -hexQuad = hexadecimalDigit hexadecimalDigit hexadecimalDigit hexadecimalDigit +hexQuad = hexadecimalDigit hexadecimalDigit hexadecimalDigit hexadecimalDigit ### @@ -1344,7 +1344,7 @@ hexQuad = hexadecimalDigit hexadecimalDigit hexadecimalDigit hexadecimalDigit # 6.4.4 -constant = characterConstant +constant = characterConstant | floatingConstant | integerConstant @@ -1352,607 +1352,616 @@ constant = characterConstant # 6.4.4.1 -integerConstant = < ( hexadecimalConstant - | octalConstant - | binaryConstant &{gnu} - | decimalConstant - ) integerSuffix? > { $$ = new_C_int(yytext); } - +integerConstant = < ( hexadecimalConstant + | octalConstant + | binaryConstant &{gnu} + | decimalConstant + ) integerSuffix? + > { $$ = new_C_int(yytext); } - -decimalConstant = [1-9][0-9]* +decimalConstant = [1-9][0-9]* -octalConstant = '0'[0-9]* +octalConstant = '0'[0-9]* -hexadecimalConstant = hexadecimalPrefix [a-fA-F0-9]+ +hexadecimalConstant = hexadecimalPrefix [a-fA-F0-9]+ -binaryConstant = '0'[bB][01]+ +binaryConstant = '0'[bB][01]+ -hexadecimalPrefix = '0'[xX] +hexadecimalPrefix = '0'[xX] -octalDigit = [0-7] +octalDigit = [0-7] -hexadecimalDigit = [0-9A-Fa-f] +hexadecimalDigit = [0-9A-Fa-f] -integerSuffix = ( [uU][lL]?[lL]? | [lL][lL]?[uU]? ) ( imaginarySuffix &{gnu} )? +integerSuffix = ( [uU][lL]?[lL]? | [lL][lL]?[uU]? ) ( imaginarySuffix &{gnu} )? -imaginarySuffix = [ij] +imaginarySuffix = [ij] # 6.4.4.2 -floatingConstant = <( decimalFloatingConstant | hexadecimalFloatingConstant )> { $$ = new_C_float(yytext); } - +floatingConstant = <( decimalFloatingConstant | hexadecimalFloatingConstant )> { $$ = new_C_float(yytext); } - -decimalFloatingConstant = fractionalConstant exponentPart? floatingSuffix? - | digitSequence exponentPart floatingSuffix? +decimalFloatingConstant = fractionalConstant exponentPart? floatingSuffix? + | digitSequence exponentPart floatingSuffix? -hexadecimalFloatingConstant = hexadecimalPrefix hexadecimalFractionalConstant binaryExponentPart floatingSuffix? - | hexadecimalPrefix hexadecimalDigitSequence binaryExponentPart floatingSuffix? +hexadecimalFloatingConstant = hexadecimalPrefix hexadecimalFractionalConstant binaryExponentPart floatingSuffix? + | hexadecimalPrefix hexadecimalDigitSequence binaryExponentPart floatingSuffix? -fractionalConstant = digitSequence '.' digitSequence? - | '.' digitSequence +fractionalConstant = digitSequence '.' digitSequence? + | '.' digitSequence -exponentPart = [eE] [-+]? digitSequence +exponentPart = [eE] [-+]? digitSequence -digitSequence = digit+ +digitSequence = digit+ -hexadecimalFractionalConstant = hexadecimalDigitSequence '.' hexadecimalDigitSequence? - | '.' hexadecimalDigitSequence +hexadecimalFractionalConstant = hexadecimalDigitSequence '.' hexadecimalDigitSequence? + | '.' hexadecimalDigitSequence -binaryExponentPart = [pP] [-+]? digitSequence +binaryExponentPart = [pP] [-+]? digitSequence -hexadecimalDigitSequence = hexadecimalDigit+ +hexadecimalDigitSequence = hexadecimalDigit+ -floatingSuffix = [fFlL] imaginarySuffix? +floatingSuffix = [fFlL] imaginarySuffix? # 6.4.4.4 -characterConstant = < "'" cCharSequence "'" > { $$ = new_C_char(yytext) } - - | < "L'" cCharSequence "'" > { $$ = new_C_char(yytext) } - +characterConstant = < "'" cCharSequence "'" > { $$ = new_C_char(yytext) } - + | < "L'" cCharSequence "'" > { $$ = new_C_char(yytext) } - -cCharSequence = ( escapeSequence | !EOL [^\'\\] )* +cCharSequence = ( escapeSequence | !EOL [^\'\\] )* -escapeSequence = simpleEscapeSequence - | octalEscapeSequence - | hexadecimalEscapeSequence - | universalCharacterName - | '\\' EOL - | '\\' Blank+ EOL &{gnu} - | '\\' . &{gnu} +escapeSequence = simpleEscapeSequence + | octalEscapeSequence + | hexadecimalEscapeSequence + | universalCharacterName + | '\\' EOL + | '\\' Blank+ EOL &{gnu} + | '\\' . &{gnu} -simpleEscapeSequence = '\\'([\'\"?\\abfnrtv] | 'e' &{gnu}) +simpleEscapeSequence = '\\'([\'\"?\\abfnrtv] | 'e' &{gnu}) -octalEscapeSequence = '\\' octalDigit octalDigit? octalDigit? +octalEscapeSequence = '\\' octalDigit octalDigit? octalDigit? -hexadecimalEscapeSequence = '\\x' hexadecimalDigit+ +hexadecimalEscapeSequence = '\\x' hexadecimalDigit+ ### A.1.6 String literals # 6.4.5 -stringLiteral = { listBegin(); } - ( s:stringLiteralPart { listAppend(s) } - )+ { $$= new_C_string(listEnd()) } +stringLiteral = { listBegin(); } + ( s:stringLiteralPart { listAppend(s) } + )+ { $$= new_C_string(listEnd()) } -stringLiteralPart = < '"' sCharSequence '"' > { $$= new_C_char(yytext) } - - | < 'L''"' sCharSequence '"' > { $$= new_C_char(yytext) } - +stringLiteralPart = < '"' sCharSequence '"' > { $$= new_C_char(yytext) } - + | < 'L''"' sCharSequence '"' > { $$= new_C_char(yytext) } - -sCharSequence = ( escapeSequence | !EOL [^\"\\] )* +sCharSequence = ( escapeSequence | !EOL [^\"\\] )* ### A.2.1 Expressions # 6.5.1 -primaryExpression = stringLiteral | constant | id - | x:mexp { $$ = eval(globals, x) } - | l:LPAREN x:expression r:RPAREN { $$= new_C_subexpr(l, x, r) } - | l:LPAREN x:compoundStatement r:RPAREN &{gnu} { $$= new_C_subexpr(l, x, r) } +primaryExpression = stringLiteral | constant | id + | META_AT META_LPAREN x:mexp { $$ = eval(globals, x) } + | l:LPAREN x:expression r:RPAREN { $$= new_C_subexpr(l, x, r) } + | l:LPAREN x:compoundStatement r:RPAREN &{gnu} { $$= new_C_subexpr(l, x, r) } # 6.5.2 -postfixExpression = o:LPAREN l:typeName p:RPAREN - a:LCURLY r:initializerList ( c:COMMA | {c=newNullObject()} ) b:RCURLY { $$= new_C_aggregate(o, l, p, a, r, c, b) } - | l:primaryExpression - ( o:LBRACKET r:expression p:RBRACKET { l= new_C_index(l, o, r, p) } - | o:LPAREN r:argumentExpressionList p:RPAREN { l= new_C_call(l, o, r, p) } - | o:DOT r:id { l= new_C_binary(l, o, r) } - | o:PTR r:id { l= new_C_binary(l, o, r) } - | o:INC { l= new_C_postfix(l, o) } - | o:DEC { l= new_C_postfix(l, o) } - )* { $$= l } - -argumentExpressionList = { listBegin() } - ( x:assignmentExpression { listAppend(x) } - ( c:COMMA x:assignmentExpression { listAppend2(c, x) } - )* - )? { $$= listEnd() } +postfixExpression = o:LPAREN l:typeName p:RPAREN + a:LCURLY r:initializerList ( c:COMMA | {c=newNullObject()} ) b:RCURLY { $$= new_C_aggregate(o, l, p, a, r, c, b) } + | l:primaryExpression + ( o:LBRACKET r:expression p:RBRACKET { l= new_C_index(l, o, r, p) } + | o:LPAREN r:argumentExpressionList p:RPAREN { l= new_C_call(l, o, r, p) } + | o:DOT r:id { l= new_C_binary(l, o, r) } + | o:PTR r:id { l= new_C_binary(l, o, r) } + | o:INC { l= new_C_postfix(l, o) } + | o:DEC { l= new_C_postfix(l, o) } + )* { $$= l } + +argumentExpressionList = { listBegin() } + ( x:assignmentExpression { listAppend(x) } + ( c:COMMA x:assignmentExpression { listAppend2(c, x) } + )* + )? { $$= listEnd() } # 6.5.3 -unaryExpression = o:INC x:unaryExpression { $$= new_C_prefix(o, x) } - | o:DEC x:unaryExpression { $$= new_C_prefix(o, x) } - | o:unaryOperator x:castExpression { $$= new_C_unary(o, x) } - | s:SIZEOF ( l:LPAREN t:typeName r:RPAREN { $$= new_C_sizeOf(s, l, t, r) } - | x:unaryExpression { $$= new_C_sizeOf(s, newNullObject(), x, newNullObject()) } - ) - | s:ALIGNOF ( l:LPAREN t:typeName r:RPAREN { $$= new_C_alignOf(s, l, t, r) } - | x:unaryExpression { $$= new_C_alignOf(s, newNullObject(), x, newNullObject()) } - ) &{gnu} - | asmExpr &{gnu} - | postfixExpression - -unaryOperator = BAND | STAR | PLUS | MINUS | BNOT | LNOT - | LAND &{gnu} - | REAL &{gnu} - | IMAG &{gnu} +unaryExpression = o:INC x:unaryExpression { $$= new_C_prefix(o, x) } + | o:DEC x:unaryExpression { $$= new_C_prefix(o, x) } + | o:unaryOperator x:castExpression { $$= new_C_unary(o, x) } + | s:SIZEOF ( l:LPAREN t:typeName r:RPAREN { $$= new_C_sizeOf(s, l, t, r) } + | x:unaryExpression { $$= new_C_sizeOf(s, newNullObject(), x, newNullObject()) } + ) + | s:ALIGNOF ( l:LPAREN t:typeName r:RPAREN { $$= new_C_alignOf(s, l, t, r) } + | x:unaryExpression { $$= new_C_alignOf(s, newNullObject(), x, newNullObject()) } + ) &{gnu} + | asmExpr &{gnu} + | postfixExpression + +unaryOperator = BAND | STAR | PLUS | MINUS | BNOT | LNOT + | LAND &{gnu} + | REAL &{gnu} + | IMAG &{gnu} # 6.5.4 -castExpression = l:LPAREN t:typeName r:RPAREN x:castExpression { $$= new_C_cast(l, t, r, x) } - | unaryExpression +castExpression = l:LPAREN t:typeName r:RPAREN x:castExpression { $$= new_C_cast(l, t, r, x) } + | unaryExpression # 6.5.5 -multiplicativeExpression = l:castExpression - ( o:multiplicativeOperator r:castExpression { l= new_C_binary(l, o, r) } - )* { $$= l } +multiplicativeExpression = l:castExpression + ( o:multiplicativeOperator r:castExpression { l= new_C_binary(l, o, r) } + )* { $$= l } -multiplicativeOperator = STAR | DIV | MOD +multiplicativeOperator = STAR | DIV | MOD # 6.5.6 -additiveExpression = l:multiplicativeExpression - ( o:additiveOperator r:multiplicativeExpression { l= new_C_binary(l, o, r) } - )* { $$= l } +additiveExpression = l:multiplicativeExpression + ( o:additiveOperator r:multiplicativeExpression { l= new_C_binary(l, o, r) } + )* { $$= l } -additiveOperator = PLUS | MINUS +additiveOperator = PLUS | MINUS # 6.5.7 -shiftExpression = l:additiveExpression - ( o:shiftOperator r:additiveExpression { l= new_C_binary(l, o, r) } - )* { $$= l } +shiftExpression = l:additiveExpression + ( o:shiftOperator r:additiveExpression { l= new_C_binary(l, o, r) } + )* { $$= l } -shiftOperator = LSHIFT | RSHIFT +shiftOperator = LSHIFT | RSHIFT # 6.5.8 -relationalExpression = l:shiftExpression - ( o:relationalOperator r:shiftExpression { l= new_C_binary(l, o, r) } - )* { $$= l } +relationalExpression = l:shiftExpression + ( o:relationalOperator r:shiftExpression { l= new_C_binary(l, o, r) } + )* { $$= l } -relationalOperator = LT | LTE | GT | GTE +relationalOperator = LT | LTE | GT | GTE # 6.5.9 -equalityExpression = l:relationalExpression - ( o:equalityOperator r:relationalExpression { l= new_C_binary(l, o, r) } - )* { $$= l } +equalityExpression = l:relationalExpression + ( o:equalityOperator r:relationalExpression { l= new_C_binary(l, o, r) } + )* { $$= l } -equalityOperator = EQUAL | NOT_EQUAL +equalityOperator = EQUAL | NOT_EQUAL # 6.5.10 -andExpression = l:equalityExpression - ( o:BAND r:equalityExpression { l= new_C_binary(l, o, r) } - )* { $$= l } +andExpression = l:equalityExpression + ( o:BAND r:equalityExpression { l= new_C_binary(l, o, r) } + )* { $$= l } # 6.5.11 -exclusiveOrExpression = l:andExpression - ( o:BXOR r:andExpression { l= new_C_binary(l, o, r) } - )* { $$= l } +exclusiveOrExpression = l:andExpression + ( o:BXOR r:andExpression { l= new_C_binary(l, o, r) } + )* { $$= l } # 6.5.12 -inclusiveOrExpression = l:exclusiveOrExpression - ( o:BOR r:exclusiveOrExpression { l= new_C_binary(l, o, r) } - )* { $$= l } +inclusiveOrExpression = l:exclusiveOrExpression + ( o:BOR r:exclusiveOrExpression { l= new_C_binary(l, o, r) } + )* { $$= l } # 6.5.13 -logicalAndExpression = l:inclusiveOrExpression - ( o:LAND r:inclusiveOrExpression { l= new_C_binary(l, o, r) } - )* { $$= l } +logicalAndExpression = l:inclusiveOrExpression + ( o:LAND r:inclusiveOrExpression { l= new_C_binary(l, o, r) } + )* { $$= l } # 6.5.14 -logicalOrExpression = l:logicalAndExpression - ( o:LOR r:logicalAndExpression { l= new_C_binary(l, o, r) } - )* { $$= l } +logicalOrExpression = l:logicalAndExpression + ( o:LOR r:logicalAndExpression { l= new_C_binary(l, o, r) } + )* { $$= l } # 6.5.15 -conditionalExpression = l:logicalOrExpression - ( q:QUESTION m:expression c:COLON r:conditionalExpression { $$= new_C_conditional(l, q, m, c, r) } - | q:QUESTION c:COLON r:conditionalExpression &{gnu} { $$= new_C_conditional(l, q, newNullObject(), c, r) } - | { $$= l } - ) +conditionalExpression = l:logicalOrExpression + ( q:QUESTION m:expression c:COLON r:conditionalExpression { $$= new_C_conditional(l, q, m, c, r) } + | q:QUESTION c:COLON r:conditionalExpression &{gnu} { $$= new_C_conditional(l, q, newNullObject(), c, r) } + | { $$= l } + ) # 6.5.16 -assignmentExpressionOpt = assignmentExpression | {$$=newNullObject()} +assignmentExpressionOpt = assignmentExpression | {$$=newNullObject()} -assignmentExpression = l:unaryExpression o:assignmentOperator r:assignmentExpression { $$= new_C_binary(l, o, r) } - | conditionalExpression +assignmentExpression = l:unaryExpression o:assignmentOperator r:assignmentExpression { $$= new_C_binary(l, o, r) } + | conditionalExpression -assignmentOperator = ASSIGN - | STAR_ASSIGN | DIV_ASSIGN | MOD_ASSIGN | PLUS_ASSIGN | MINUS_ASSIGN - | LSHIFT_ASSIGN | RSHIFT_ASSIGN | BAND_ASSIGN | BXOR_ASSIGN | BOR_ASSIGN +assignmentOperator = ASSIGN + | STAR_ASSIGN | DIV_ASSIGN | MOD_ASSIGN | PLUS_ASSIGN | MINUS_ASSIGN + | LSHIFT_ASSIGN | RSHIFT_ASSIGN | BAND_ASSIGN | BXOR_ASSIGN | BOR_ASSIGN # 6.5.17 -expression = l:assignmentExpression - ( o:COMMA r:assignmentExpression { l= new_C_binary(l, o, r) } - )* { $$= l } +expression = l:assignmentExpression + ( o:COMMA r:assignmentExpression { l= new_C_binary(l, o, r) } + )* { $$= l } -expressionOpt = expression | { $$= newNullObject() } +expressionOpt = expression | { $$= newNullObject() } -constantExpression = conditionalExpression +constantExpression = conditionalExpression ### A.2.2 Declarations # 6.7 -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) } - # Any list of specifiers and qualifiers at the start of a declaration may contain attribute specifiers - | s:attributeSpecifier &{gnu} { listAppend(s) } - | s:typedefName &{ !specified++ } { listAppend(s) } - | s:typeQualifier { listAppend(s) } - | s:functionSpecifier { listAppend(s) } - )+ { $$= listEnd() } - | &{gnu} { $$= listEmpty() } - -initDeclaratorListOpt = initDeclaratorList | { $$= listEmpty() } - -initDeclaratorList = d:initDeclarator { listWith(d) } - ( c:COMMA d:initDeclarator { listAppend2(c, d) } - )* { $$= listEnd() } - -initDeclarator = d:declarator - ( a:ASSIGN i:initializer &{ !typedeffing } { d= new_C_binary(d, a, i) } - )? { $$= d } +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) } + # Any list of specifiers and qualifiers at the start + # of a declaration may contain attribute specifiers + | s:attributeSpecifier &{gnu} { listAppend(s) } + | s:typedefName &{ !specified++ } { listAppend(s) } + | s:typeQualifier { listAppend(s) } + | s:functionSpecifier { listAppend(s) } + )+ { $$= listEnd() } + | &{gnu} { $$= listEmpty() } + +initDeclaratorListOpt = initDeclaratorList | { $$= listEmpty() } + +initDeclaratorList = d:initDeclarator { listWith(d) } + ( c:COMMA d:initDeclarator { listAppend2(c, d) } + )* { $$= listEnd() } + +initDeclarator = d:declarator + ( a:ASSIGN i:initializer &{ !typedeffing } { d= new_C_binary(d, a, i) } + )? { $$= d } # 6.7.1 -storageClassSpecifier = TYPEDEF @{ declarationTypedef() } - | AUTO - | parameterStorageClassSpecifier - | functionStorageClassSpecifier +storageClassSpecifier = TYPEDEF @{ declarationTypedef() } + | AUTO + | parameterStorageClassSpecifier + | functionStorageClassSpecifier -parameterStorageClassSpecifier = REGISTER +parameterStorageClassSpecifier = REGISTER -functionStorageClassSpecifier = EXTERN | STATIC +functionStorageClassSpecifier = EXTERN | STATIC # 6.7.2 -typeSpecifier = VOID | CHAR | SHORT | INT | LONG | FLOAT | DOUBLE | SIGNED | UNSIGNED | BOOL | COMPLEX - | ( BUILTIN_VA_LIST | _FLOAT128 ) - | structOrUnionSpecifier - | enumSpecifier +typeSpecifier = VOID | CHAR | SHORT | INT | LONG | FLOAT | DOUBLE | SIGNED | UNSIGNED | BOOL | COMPLEX + | ( BUILTIN_VA_LIST | _FLOAT128 ) + | structOrUnionSpecifier + | enumSpecifier # 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=newNullObject()} ) - ( i:idOpt ( @{ C_scopeBegin() } - l:LCURLY d:structDeclarationList r:RCURLY - @{ C_scopeEnd() } - | &{ C_scopeAbort() } - ) - # ..., or after the closing brace. - ( b:attributeSpecifiers &{gnu} | {b=newNullObject()} ) - | i:id {l=d=r=b=newNullObject()} - ) { $$= new_C_structSpec(s, a, i, l, d, r, b) } - -structOrUnion = STRUCT | UNION - -structDeclarationList = d:structDeclaration { listWith(d) } - ( d:structDeclaration { listAppend(d) } - )* { $$= listEnd() } - | &{gnu} { $$= newNullObject() } - -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++ } - | t:typedefName &{ !specified++ } - | t:typeQualifier - ) { listAppend(t) } - )+ { $$= listEnd() } - -structDeclaratorList = d:structDeclarator { listWith(d) } - ( c:COMMA d:structDeclarator { listAppend2(c, d) } - )* { $$= listEnd() } - | &{gnu} { $$= newNullObject() } - -structDeclarator = ( c:COLON e:constantExpression { d= new_C_structDeclarator(newNullObject(), c, e) } - | d:declarator ( c:COLON e:constantExpression | {c=e=newNullObject()} ) { 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 } +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=newNullObject()} ) + ( i:idOpt ( @{ C_scopeBegin() } + l:LCURLY d:structDeclarationList r:RCURLY + @{ C_scopeEnd() } + | &{ C_scopeAbort() } + ) + # ..., or after the closing brace. + ( b:attributeSpecifiers &{gnu} | {b=newNullObject()} ) + | i:id {l=d=r=b=newNullObject()} + ) { $$= new_C_structSpec(s, a, i, l, d, r, b) } + +structOrUnion = STRUCT | UNION + +structDeclarationList = d:structDeclaration { listWith(d) } + ( d:structDeclaration { listAppend(d) } + )* { $$= listEnd() } + | &{gnu} { $$= newNullObject() } + +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++ } + | t:typedefName &{ !specified++ } + | t:typeQualifier + ) { listAppend(t) } + )+ { $$= listEnd() } + +structDeclaratorList = d:structDeclarator { listWith(d) } + ( c:COMMA d:structDeclarator { listAppend2(c, d) } + )* { $$= listEnd() } + | &{gnu} { $$= newNullObject() } + +structDeclarator = ( c:COLON e:constantExpression { d= new_C_structDeclarator(newNullObject(), c, e) } + | d:declarator ( c:COLON e:constantExpression | {c=e=newNullObject()} ) { 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, newNullObject(), newNullObject(), newNullObject()) } - ) +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, newNullObject(), newNullObject(), newNullObject()) } + ) -enumeratorList = e:enumerator { listWith(e) } - ( c:COMMA e:enumerator { listAppend(c); listAppend(e) } - )* - ( c:COMMA { listAppend(c) } - )? { $$= listEnd() } +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=newNullObject()} ) { $$= new_C_enumerator(i, a, e) } +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=newNullObject()} ) { $$= new_C_enumerator(i, a, e) } # 6.7.3 -typeQualifier = CONST | RESTRICT | VOLATILE - | __RESTRICT +typeQualifier = CONST | RESTRICT | VOLATILE + | __RESTRICT # 6.7.4 -functionSpecifier = INLINE - | __INLINE +functionSpecifier = INLINE + | __INLINE # 6.7.5 -declarator = # An attribute specifier list may appear immediately before a declarator - a:attributeSpecifier d:declarator &{gnu} { $$= new_C_attribution(a, d) } - | p:STAR q:typeQualifierList d:declarator { $$= new_C_deref(p, q, d) } - | p:BXOR q:typeQualifierList d:declarator &{apl} { $$= new_C_block(p, q, d) } - | ( d:directDeclarator - # An attribute specifier list may appear immediately before the comma, = or semicolon terminating the declaration of an identifier - ( &{gnu} a:attributeSpecifier { d= new_C_attribution(d, a) } - # an asm (or __asm__) keyword may appear after the declarator - | &{gnu} a:asm { d= new_C_attribution(d, a) } - )* - ) { $$= d } - -directDeclarator = ( l:LPAREN d:declarator r:RPAREN { d= new_C_subexpr(l, d, r) } - | &( @{ declarationId(yytext) } ) - d:id - ) ( @{ C_scopeBegin() } - ( l:LPAREN p:parameterTypeList r:RPAREN { d= new_C_call (d, l, p, r) } - @{ C_scopeEnd() } - | l:LPAREN p:identifierListOpt r:RPAREN { d= new_C_call (d, l, p, r) } - @{ C_scopeEnd() } - | l:LBRACKET ( s:STATIC q:typeQualifierListOpt {t=newNullObject()} e:assignmentExpression - | {s=newNullObject()} q:typeQualifierList t:STATIC e:assignmentExpressionOpt - | {s=newNullObject()} q:typeQualifierListOpt t:STAR {e=newNullObject()} - | {s=newNullObject()} q:typeQualifierListOpt {t=newNullObject()} e:assignmentExpressionOpt ) r:RBRACKET { d= new_C_array(d, l, s, q, t, e, r) } - @{ C_scopeEnd() } - | &{ C_scopeAbort() } - ) - )* { $$= d } - -typeQualifierListOpt = typeQualifierList | {$$=newNullObject()} - -typeQualifierList = { listBegin() } - ( t:typeQualifier { listAppend(t) } - )* { $$= listEnd() } - -parameterTypeListOpt = parameterTypeList | {$$=newNullObject()} - -parameterTypeList = p:parameterList - ( c:COMMA v:ELLIPSIS { List_addLast(p, c); List_addLast(p, v) } - )? { $$= p } - -parameterList = p:parameterDeclaration { listWith(p) } - ( ( c:COMMA | c:SEMI &{gnu} ) { listAppend(c) } - p:parameterDeclaration { listAppend(p) } - )* { $$= listEnd() } - -parameterDeclaration = s:parameterDeclarationSpecifiers - ( d:declarator | d:abstractDeclaratorOpt ) { $$= new_C_parameter(s, d) } - -parameterDeclarationSpecifiers - = @{ int specified= 0 } { listBegin() } - ( s:parameterStorageClassSpecifier { listAppend(s) } - | s:typeSpecifier @{ specified++ } { listAppend(s) } - | s:typedefName &{ !specified++ } { listAppend(s) } - | s:typeQualifier { listAppend(s) } - | s:functionSpecifier { listAppend(s) } - )+ { $$= listEnd() } - -identifierListOpt = identifierList | {$$=newNullObject()} - -identifierList = i:id { listWith(i) } - ( c:COMMA i:id { listAppend2(c, i) } - )* { $$= listEnd() } +declarator = # An attribute specifier list may appear immediately before a declarator + a:attributeSpecifier d:declarator &{gnu} { $$= new_C_attribution(a, d) } + | p:STAR q:typeQualifierList d:declarator { $$= new_C_deref(p, q, d) } + | p:BXOR q:typeQualifierList d:declarator &{apl} { $$= new_C_block(p, q, d) } + | ( d:directDeclarator + # An attribute specifier list may appear immediately + # before the comma, = or semicolon terminating the declaration of an identifier + ( &{gnu} a:attributeSpecifier { d= new_C_attribution(d, a) } + # an asm (or __asm__) keyword may appear after the declarator + | &{gnu} a:asm { d= new_C_attribution(d, a) } + )* + ) { $$= d } + +directDeclarator = ( l:LPAREN d:declarator r:RPAREN { d= new_C_subexpr(l, d, r) } + | &( @{ declarationId(yytext) } ) + d:id + ) + ( @{ C_scopeBegin() } + ( l:LPAREN p:parameterTypeList r:RPAREN { d= new_C_call (d, l, p, r) } + @{ C_scopeEnd() } + | l:LPAREN p:identifierListOpt r:RPAREN { d= new_C_call (d, l, p, r) } + @{ C_scopeEnd() } + | l:LBRACKET ( s:STATIC q:typeQualifierListOpt {t=newNullObject()} e:assignmentExpression + | {s=newNullObject()} q:typeQualifierList + t:STATIC e:assignmentExpressionOpt + | {s=newNullObject()} q:typeQualifierListOpt + t:STAR {e=newNullObject()} + | {s=newNullObject()} q:typeQualifierListOpt {t=newNullObject()} + e:assignmentExpressionOpt ) r:RBRACKET { d= new_C_array(d, l, s, q, t, e, r) } + @{ C_scopeEnd() } + | &{ C_scopeAbort() } + ) + )* { $$= d } + +typeQualifierListOpt = typeQualifierList | {$$=newNullObject()} + +typeQualifierList = { listBegin() } + ( t:typeQualifier { listAppend(t) } + )* { $$= listEnd() } + +parameterTypeListOpt = parameterTypeList | {$$=newNullObject()} + +parameterTypeList = p:parameterList + ( c:COMMA v:ELLIPSIS { List_addLast(p, c); List_addLast(p, v) } + )? { $$= p } + +parameterList = p:parameterDeclaration { listWith(p) } + ( ( c:COMMA | c:SEMI &{gnu} ) { listAppend(c) } + p:parameterDeclaration { listAppend(p) } + )* { $$= listEnd() } + +parameterDeclaration = s:parameterDeclarationSpecifiers + ( d:declarator | d:abstractDeclaratorOpt ) { $$= new_C_parameter(s, d) } + +parameterDeclarationSpecifiers = @{ int specified= 0 } { listBegin() } + ( s:parameterStorageClassSpecifier { listAppend(s) } + | s:typeSpecifier @{ specified++ } { listAppend(s) } + | s:typedefName &{ !specified++ } { listAppend(s) } + | s:typeQualifier { listAppend(s) } + | s:functionSpecifier { listAppend(s) } + )+ { $$= listEnd() } + +identifierListOpt = identifierList | {$$=newNullObject()} + +identifierList = i:id { listWith(i) } + ( c:COMMA i:id { listAppend2(c, i) } + )* { $$= listEnd() } # 6.7.6 -typeName = s:specifierQualifierList d:abstractDeclaratorOpt { $$= new_C_declaration(s, d, newNullObject()) } +typeName = s:specifierQualifierList d:abstractDeclaratorOpt { $$= new_C_declaration(s, d, newNullObject()) } -abstractDeclaratorOpt = abstractDeclarator | {$$=newNullObject()} +abstractDeclaratorOpt = abstractDeclarator | {$$=newNullObject()} -abstractDeclarator = p:STAR q:typeQualifierList d:abstractDeclaratorOpt { $$= new_C_deref(p, q, d) } - | p:BXOR q:typeQualifierList d:abstractDeclaratorOpt &{apl} { $$= new_C_block(p, q, d) } - | directAbstractDeclarator +abstractDeclarator = p:STAR q:typeQualifierList d:abstractDeclaratorOpt { $$= new_C_deref(p, q, d) } + | p:BXOR q:typeQualifierList d:abstractDeclaratorOpt &{apl} { $$= new_C_block(p, q, d) } + | directAbstractDeclarator -directAbstractDeclarator= @{int nonEmpty= 0} - ( l:LPAREN d:abstractDeclarator r:RPAREN @{++nonEmpty} { d= new_C_subexpr(l, d, r) } - | {d=newNullObject()} - ) ( l:LPAREN p:parameterTypeListOpt r:RPAREN @{++nonEmpty} { d= new_C_call (d, l, p, r) } - | l:LBRACKET - ( s:STATIC q:typeQualifierListOpt {t=newNullObject()} e:assignmentExpression - | {s=newNullObject()} q:typeQualifierList t:STATIC e:assignmentExpressionOpt - | {s=newNullObject()} q:typeQualifierListOpt t:STAR {e=newNullObject()} - | {s=newNullObject()} q:typeQualifierListOpt {t=newNullObject()} e:assignmentExpressionOpt - ) r:RBRACKET @{++nonEmpty} { d= new_C_array(d, l, s, q, t, e, r) } - )* &{nonEmpty} { $$= d } +directAbstractDeclarator = @{int nonEmpty= 0} + ( l:LPAREN d:abstractDeclarator r:RPAREN @{++nonEmpty} { d= new_C_subexpr(l, d, r) } + | {d=newNullObject()} + ) + ( l:LPAREN p:parameterTypeListOpt r:RPAREN @{++nonEmpty} { d= new_C_call (d, l, p, r) } + | l:LBRACKET + ( s:STATIC q:typeQualifierListOpt {t=newNullObject()} e:assignmentExpression + | {s=newNullObject()} q:typeQualifierList t:STATIC e:assignmentExpressionOpt + | {s=newNullObject()} q:typeQualifierListOpt t:STAR {e=newNullObject()} + | {s=newNullObject()} q:typeQualifierListOpt {t=newNullObject()} e:assignmentExpressionOpt + ) r:RBRACKET @{++nonEmpty} { d= new_C_array(d, l, s, q, t, e, r) } + )* &{nonEmpty} { $$= d } # 6.7.7 -typedefName = &{ isTypedefName(yytext) } { $$= new_C_id(yytext) } - - | t:TYPEOF l:LPAREN - ( x:expression r:RPAREN { $$= new_C_typeOf(t, l, newNullObject(), x, r) } - | x:typeName r:RPAREN { $$= new_C_typeOf(t, l, x, newNullObject(), r) } - ) &{gnu} +typedefName = &{ isTypedefName(yytext) } { $$= new_C_id(yytext) } - + | t:TYPEOF l:LPAREN + ( x:expression r:RPAREN { $$= new_C_typeOf(t, l, newNullObject(), x, r) } + | x:typeName r:RPAREN { $$= new_C_typeOf(t, l, x, newNullObject(), r) } + ) &{gnu} # 6.7.8 -initializer = l:LCURLY i:initializerList ( c:COMMA | {c=newNullObject()} ) r:RCURLY { $$= new_C_initializer(l, i, c, r) } - | assignmentExpression +initializer = l:LCURLY i:initializerList ( c:COMMA | {c=newNullObject()} ) r:RCURLY { $$= new_C_initializer(l, i, c, r) } + | assignmentExpression -initializerList = { listBegin() } - ( d:designation { listAppend(d) } - )? i:initializer { listAppend(i) } - ( c:COMMA { listAppend(c) } - ( d:designation { listAppend(d) } - )? i:initializer { listAppend(i) } - )* { $$= listEnd() } - | &{gnu} { $$= newNullObject() } +initializerList = { listBegin() } + ( d:designation { listAppend(d) } + )? i:initializer { listAppend(i) } + ( c:COMMA { listAppend(c) } + ( d:designation { listAppend(d) } + )? i:initializer { listAppend(i) } + )* { $$= listEnd() } + | &{gnu} { $$= newNullObject() } -designation = ( d:designatorList ( a:ASSIGN | {a=newNullObject()} &{gnu} ) - | d:id a:COLON &{gnu} - ) { $$= new_C_designation(d, a) } +designation = ( d:designatorList ( a:ASSIGN | {a=newNullObject()} &{gnu} ) + | d:id a:COLON &{gnu} + ) { $$= new_C_designation(d, a) } -designatorList = { listBegin() } - ( l:LBRACKET x:constantExpression r:RBRACKET { listAppend(new_C_index(newNullObject(), l, x, r)) } - | l:LBRACKET x:constantRange r:RBRACKET &{gnu} { listAppend(new_C_index(newNullObject(), l, x, r)) } - | l:DOT x:id { listAppend(new_C_binary(newNullObject(), l, x)) } - )+ { $$= listEnd() } +designatorList = { listBegin() } + ( l:LBRACKET x:constantExpression r:RBRACKET { listAppend(new_C_index(newNullObject(), l, x, r)) } + | l:LBRACKET x:constantRange r:RBRACKET &{gnu} { listAppend(new_C_index(newNullObject(), l, x, r)) } + | l:DOT x:id { listAppend(new_C_binary(newNullObject(), l, x)) } + )+ { $$= listEnd() } ### A.2.3 Statements # 6.8 -statement = expressionStatement - | labeledStatement - | compoundStatement - | selectionStatement - | iterationStatement - | jumpStatement +statement = expressionStatement + | labeledStatement + | compoundStatement + | selectionStatement + | iterationStatement + | jumpStatement # 6.8.1 -labeledStatement = i:id c:COLON - # an attribute specifier list may appear after the colon following a label, other than a case or default label - ( a:attributeSpecifiers &{gnu} | {a=newNullObject()} ) - s:statement { $$= new_C_label(i, c, a, s) } - | c:CASE x:constantExpression d:COLON s:statement { $$= new_C_case(c, x, d, s) } - | c:CASE x:constantRange d:COLON s:statement &{gnu} { $$= new_C_case(c, x, d, s) } - | d:DEFAULT c:COLON s:statement { $$= new_C_default(d, c, s) } +labeledStatement = i:id c:COLON + # an attribute specifier list may appear after + # the colon following a label, other than a case or default label + ( a:attributeSpecifiers &{gnu} | {a=newNullObject()} ) + s:statement { $$= new_C_label(i, c, a, s) } + | c:CASE x:constantExpression d:COLON s:statement { $$= new_C_case(c, x, d, s) } + | c:CASE x:constantRange d:COLON s:statement &{gnu} { $$= new_C_case(c, x, d, s) } + | d:DEFAULT c:COLON s:statement { $$= new_C_default(d, c, s) } # 6.8.2 -compoundStatement = @{ C_scopeBegin() } - l:LCURLY { listBegin() } - ( x:localLabelDeclaration &{gnu} { listAppend(x) } - )* - ( x:declaration { listAppend(x) } - | x:statement { listAppend(x) } - | x:functionDefinition &{gnu} { listAppend(x) } - | !'}' &{ errmsg= "statement expected" } error - )* { x= listEnd() } - r:RCURLY { $$= new_C_compound(l, x, r) } - @{ C_scopeEnd() } - | &{ C_scopeAbort() } +compoundStatement = @{ C_scopeBegin() } + l:LCURLY { listBegin() } + ( x:localLabelDeclaration &{gnu} { listAppend(x) } + )* + ( x:declaration { listAppend(x) } + | x:statement { listAppend(x) } + | x:functionDefinition &{gnu} { listAppend(x) } + | !'}' &{ errmsg= "statement expected" } error + )* { x= listEnd() } + r:RCURLY { $$= new_C_compound(l, x, r) } + @{ C_scopeEnd() } + | &{ C_scopeAbort() } # 6.8.3 -expressionStatement = SEMI - | x:expression s:SEMI { $$= new_C_exprStatement(x, s) } +expressionStatement = SEMI + | x:expression s:SEMI { $$= new_C_exprStatement(x, s) } # 6.8.4 -selectionStatement = i:IF l:LPAREN x:expression r:RPAREN s:statement - ( e:ELSE t:statement | {e=t=newNullObject()} ) { $$= new_C_if(i, l, x, r, s, e, t) } - | s:SWITCH l:LPAREN x:expression r:RPAREN t:statement { $$= new_C_switch(s, l, x, r, t) } +selectionStatement = i:IF l:LPAREN x:expression r:RPAREN s:statement + ( e:ELSE t:statement | {e=t=newNullObject()} ) { $$= new_C_if(i, l, x, r, s, e, t) } + | s:SWITCH l:LPAREN x:expression r:RPAREN t:statement { $$= new_C_switch(s, l, x, r, t) } # 6.8.5 -iterationStatement = w:WHILE l:LPAREN x:expression r:RPAREN s:statement { $$= new_C_while(w, l, x, r, s) } - | d:DO s:statement w:WHILE l:LPAREN x:expression r:RPAREN t:SEMI { $$= new_C_do(d, s, w, l, x, r, t) } - | f:FOR l:LPAREN a:expressionOpt t:SEMI b:expressionOpt u:SEMI - c:expressionOpt r:RPAREN s:statement { $$= new_C_for(f, l, a, t, b, u, c, r, s) } - | f:FOR l:LPAREN a:declaration b:expressionOpt u:SEMI - c:expressionOpt r:RPAREN s:statement { $$= new_C_for(f, l, a, newNullObject(), b, u, c, r, s) } +iterationStatement = w:WHILE l:LPAREN x:expression r:RPAREN s:statement { $$= new_C_while(w, l, x, r, s) } + | d:DO s:statement w:WHILE l:LPAREN x:expression r:RPAREN t:SEMI { $$= new_C_do(d, s, w, l, x, r, t) } + | f:FOR l:LPAREN a:expressionOpt t:SEMI b:expressionOpt u:SEMI + c:expressionOpt r:RPAREN s:statement { $$= new_C_for(f, l, a, t, b, u, c, r, s) } + | f:FOR l:LPAREN a:declaration b:expressionOpt u:SEMI + c:expressionOpt r:RPAREN s:statement { $$= new_C_for(f, l, a, newNullObject(), b, u, c, r, s) } # 6.8.6 -jumpStatement = g:GOTO i:id t:SEMI { $$= new_C_goto(g, newNullObject(), i, t) } - | c:CONTINUE t:SEMI { $$= new_C_continue(c, t) } - | b:BREAK t:SEMI { $$= new_C_break(b, t) } - | r:RETURN x:expressionOpt t:SEMI { $$= new_C_return(r, x, t) } - | g:GOTO s:STAR x:expression t:SEMI &{gnu} { $$= new_C_goto(g, s, x, t) } +jumpStatement = g:GOTO i:id t:SEMI { $$= new_C_goto(g, newNullObject(), i, t) } + | c:CONTINUE t:SEMI { $$= new_C_continue(c, t) } + | b:BREAK t:SEMI { $$= new_C_break(b, t) } + | r:RETURN x:expressionOpt t:SEMI { $$= new_C_return(r, x, 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+ - -externalDeclaration = { $$ = newComment(yytext); } - | ( SEMI &{gnu} - | declaration - | functionDefinition - | &. &{ errmsg= "declaration expected" } error - ) - -functionDefinition = @{ C_declarationBegin() } - ( s:functionDeclarationSpecifiers | &{gnu} {s=newNullObject()} ) - d:declarator - l:declarationListOpt - c:compoundStatement { $$= new_C_functionDef(s, d, l, c) } - @{ C_declarationEnd() } - | &{ C_declarationAbort() } - -functionDeclarationSpecifiers - = @{ int specified= 0 } { listBegin() } - ( s:functionStorageClassSpecifier { listAppend(s) } - | s:typeSpecifier @{ ++specified } { listAppend(s) } - | &{ !specified } s:typedefName @{ ++specified } { listAppend(s) } - | s:typeQualifier { listAppend(s) } - | s:functionSpecifier { listAppend(s) } - )+ { $$= listEnd() } - -declarationListOpt = declarationList | {$$=newNullObject()} - -declarationList = d:declaration { listWith(d); } - ( d:declaration { listAppend(d) } - )* { $$= listEnd() } +## translationUnit = externalDeclaration+ + +externalDeclaration = { $$ = newComment(yytext); } + | ( SEMI &{gnu} + | declaration + | functionDefinition + | &. &{ errmsg= "declaration expected" } error + ) + +functionDefinition = @{ C_declarationBegin() } + ( s:functionDeclarationSpecifiers | &{gnu} {s=newNullObject()} ) + d:declarator + l:declarationListOpt + c:compoundStatement { $$= new_C_functionDef(s, d, l, c) } + @{ C_declarationEnd() } + | &{ C_declarationAbort() } + +functionDeclarationSpecifiers = @{ int specified= 0 } { listBegin() } + ( s:functionStorageClassSpecifier { listAppend(s) } + | s:typeSpecifier @{ ++specified } { listAppend(s) } + | &{ !specified } s:typedefName @{ ++specified } { listAppend(s) } + | s:typeQualifier { listAppend(s) } + | s:functionSpecifier { listAppend(s) } + )+ { $$= listEnd() } + +declarationListOpt = declarationList | {$$=newNullObject()} + +declarationList = d:declaration { listWith(d); } + ( d:declaration { listAppend(d) } + )* { $$= listEnd() } ### GNU C extensions # An attribute specifier is of the form __attribute__ ((attribute-list)). An attribute list is a # possibly empty comma-separated sequence of attributes -attributeSpecifier = a:ATTRIBUTE ll:LPAREN lr:LPAREN { listBegin() } - ( b:attribute { listAppend(b) } - )? ( c:COMMA { listAppend(c) } - ( b:attribute { listAppend(b) } - )? )* rl:RPAREN rr:RPAREN { $$= new_C_attributeSpec(a, ll, lr, listEnd(), rl, rr) } +attributeSpecifier = a:ATTRIBUTE ll:LPAREN lr:LPAREN { listBegin() } + ( b:attribute { listAppend(b) } + )? + ( c:COMMA { listAppend(c) } + ( b:attribute { listAppend(b) } + )? + )* rl:RPAREN rr:RPAREN { $$= new_C_attributeSpec(a, ll, lr, listEnd(), rl, rr) } -attributeSpecifiers = &ATTRIBUTE { listBegin() } - a:attributeSpecifier { listAppend(a) } - ( a:attributeSpecifier { listAppend(a) } - )* { $$= listEnd() } +attributeSpecifiers = &ATTRIBUTE { listBegin() } + a:attributeSpecifier { listAppend(a) } + ( a:attributeSpecifier { listAppend(a) } + )* { $$= listEnd() } # where each attribute is one of the following: # Empty. Empty attributes are ignored. @@ -1960,431 +1969,425 @@ attributeSpecifiers = &ATTRIBUTE { listBegin() } # An attribute name followed by a parenthesized list of parameters for the attribute. These parameters take one of the following forms: # An identifier. For example, mode attributes use this form. # An identifier followed by a comma and a non-empty comma-separated list of expressions. For example, format attributes use this form. -# A possibly empty comma-separated list of expressions. For example, format_arg attributes use this +# A possibly empty comma-separated list of expressions. For example, format_arg attributes use this # form with the list being a single integer constant expression, and alias attributes use # this form with the list being a single string constant. -attribute = n:name ( l:LPAREN { listBegin() } - ( p:expression { listAppend(p) } - ( p:COMMA { listAppend(p) } - p:expression { listAppend(p) } - )* - )? - r:RPAREN { p= listEnd() } - | {l=p=r=newNullObject()} - ) { $$= new_C_attribute(n, l, p, r) } - -constantRange = a:constantExpression e:ELLIPSIS b:constantExpression { $$= new_C_range(a, e, b) } - -localLabelDeclaration = l:LABEL &{gnu} { listBegin() } - i:id { listAppend(i) } - ( c:COMMA i:id { listAppend2(c, i) } - )* - ( c:COMMA { listAppend(c) } - )? - s:SEMI { $$= new_C_labelDeclaration(l, listEnd(), s) } - -asm = a:ASM l:LPAREN s:stringLiteral r:RPAREN { $$= new_C_asm(a, l, s, r) } - -asmExpr = a:ASM ( v:VOLATILE | {v=newNullObject()} ) ( g:GOTO | {g=newNullObject()} ) - l:LPAREN s:stringLiteral { listBegin() } - ( c:COLON { listAppend(c) } - ( p:asmExprArgs { listAppend(p) } - )? - ( c:COLON { listAppend(c) } - ( p:asmExprArgs { listAppend(p) } - )? - ( c:COLON { listAppend(c) } - ( p:stringLiteralList { listAppend(p) } - )? - ( c:COLON { listAppend(c) } - ( p:ids { listAppend(p) } - )? - )? - )? - )? - )? - r:RPAREN { $$= new_C_asmExpr(a, v, g, l, s, listEnd(), r) } - -asmExprArgs = a:asmExprArg { listWith(a) } - ( c:COMMA a:asmExprArg { listAppend2(c, a) } - )* { $$= listEnd() } - -asmExprArg = s:stringLiteral ( l:LPAREN e:expression r:RPAREN | {l=e=r=newNullObject()} ){ $$= new_C_asmExprArg(s, l, e, r) } - -stringLiteralList = s:stringLiteral { listWith(s) } - ( c:COMMA s:stringLiteral { listAppend2(c, s) } - )* { $$= listEnd() } - -ids = i:id { listWith(i) } - ( c:COMMA i:id { listAppend2(c, i) } - )* { $$= listEnd() } +attribute = n:name + ( l:LPAREN { listBegin() } + ( p:expression { listAppend(p) } + ( p:COMMA { listAppend(p) } + p:expression { listAppend(p) } + )* + )? + r:RPAREN { p= listEnd() } + | {l=p=r=newNullObject()} + ) { $$= new_C_attribute(n, l, p, r) } + +constantRange = a:constantExpression e:ELLIPSIS b:constantExpression { $$= new_C_range(a, e, b) } + +localLabelDeclaration = l:LABEL &{gnu} { listBegin() } + i:id { listAppend(i) } + ( c:COMMA i:id { listAppend2(c, i) } + )* + ( c:COMMA { listAppend(c) } + )? + s:SEMI { $$= new_C_labelDeclaration(l, listEnd(), s) } + +asm = a:ASM l:LPAREN s:stringLiteral r:RPAREN { $$= new_C_asm(a, l, s, r) } + +asmExpr = a:ASM ( v:VOLATILE | {v=newNullObject()} ) ( g:GOTO | {g=newNullObject()} ) + l:LPAREN s:stringLiteral { listBegin() } + ( c:COLON { listAppend(c) } + ( p:asmExprArgs { listAppend(p) } + )? + ( c:COLON { listAppend(c) } + ( p:asmExprArgs { listAppend(p) } + )? + ( c:COLON { listAppend(c) } + ( p:stringLiteralList { listAppend(p) } + )? + ( c:COLON { listAppend(c) } + ( p:ids { listAppend(p) } + )? + )? + )? + )? + )? + r:RPAREN { $$= new_C_asmExpr(a, v, g, l, s, listEnd(), r) } + +asmExprArgs = a:asmExprArg { listWith(a) } + ( c:COMMA a:asmExprArg { listAppend2(c, a) } + )* { $$= listEnd() } + +asmExprArg = s:stringLiteral ( l:LPAREN e:expression r:RPAREN | {l=e=r=newNullObject()} ){ $$= new_C_asmExprArg(s, l, e, r) } + +stringLiteralList = s:stringLiteral { listWith(s) } + ( c:COMMA s:stringLiteral { listAppend2(c, s) } + )* { $$= listEnd() } + +ids = i:id { listWith(i) } + ( c:COMMA i:id { listAppend2(c, i) } + )* { $$= listEnd() } ### -ASSIGN = '=' !'=' { $$= newToken("=" ) } - -COLON = ':' { $$= newToken(":" ) } - -COMMA = ',' { $$= newToken("," ) } - -QUESTION = '?' { $$= newToken("?" ) } - -SEMI = ';' { $$= newToken(";" ) } - - -PTR = "->" { $$= newToken("->" ) } - - -DOT = '.' !'.' { $$= newToken("." ) } - -ELLIPSIS = '...' { $$= newToken("..." ) } - - -LPAREN = '(' { $$= newToken("(" ) } - -RPAREN = ')' { $$= newToken(")" ) } - -LBRACKET = '[' { $$= newToken("[" ) } - -RBRACKET = ']' { $$= newToken("]" ) } - -LCURLY = '{' { $$= newBegin( ) } - -RCURLY = '}' { $$= newEnd ( ) } - - -EQUAL = "==" { $$= newToken("==" ) } - -NOT_EQUAL = "!=" { $$= newToken("!=" ) } - -LTE = "<=" { $$= newToken("<=" ) } - -LT = "<" !'=' { $$= newToken("<" ) } - -GTE = ">=" { $$= newToken(">=" ) } - -GT = ">" !'=' { $$= newToken(">" ) } - - -DIV = '/' ![=*] { $$= newToken("/" ) } - -DIV_ASSIGN = "/=" { $$= newToken("/=" ) } - -PLUS = '+' ![+=] { $$= newToken("+" ) } - -PLUS_ASSIGN = "+=" { $$= newToken("+=" ) } - -INC = "++" { $$= newToken("++" ) } - -MINUS = '-' ![-=] { $$= newToken("-" ) } - -MINUS_ASSIGN = "-=" { $$= newToken("-=" ) } - -DEC = "--" { $$= newToken("--" ) } - -STAR = '*' !'=' { $$= newToken("*" ) } - -STAR_ASSIGN = "*=" { $$= newToken("*=" ) } - -MOD = '%' !'=' { $$= newToken("%" ) } - -MOD_ASSIGN = "%=" { $$= newToken("%=" ) } - -RSHIFT = ">>" !'=' { $$= newToken(">>" ) } - -RSHIFT_ASSIGN = ">>=" { $$= newToken(">>=" ) } - -LSHIFT = "<<" !'=' { $$= newToken("<<" ) } - -LSHIFT_ASSIGN = "<<=" { $$= newToken("<<=" ) } - - -LAND = "&&" { $$= newToken("&&" ) } - -LNOT = '!' !'=' { $$= newToken("!" ) } - -LOR = "||" { $$= newToken("||" ) } - - -BAND = '&' ![&=] { $$= newToken("&" ) } - -BAND_ASSIGN = "&=" { $$= newToken("&=" ) } - -BNOT = '~' { $$= newToken("~" ) } - -BOR = '|' ![|=] { $$= newToken("|" ) } - -BOR_ASSIGN = "|=" { $$= newToken("|=" ) } - -BXOR = '^' !'=' { $$= newToken("^" ) } - -BXOR_ASSIGN = "^=" { $$= newToken("^=" ) } - - -ALIGNOF = '__alignof__' !IDREST { $$= newToken("__alignof__" ) } - - | '__alignof' !IDREST { $$= newToken("__alignof" ) } - -ASM = 'asm' !IDREST { $$= newToken("asm" ) } - - | '__asm' !IDREST { $$= newToken("__asm" ) } - - | '__asm__' !IDREST { $$= newToken("__asm__" ) } - +ASSIGN = '=' !'=' { $$= newToken("=" ) } - +COLON = ':' { $$= newToken(":" ) } - +COMMA = ',' { $$= newToken("," ) } - +QUESTION = '?' { $$= newToken("?" ) } - +SEMI = ';' { $$= newToken(";" ) } - + +PTR = "->" { $$= newToken("->" ) } - + +DOT = '.' !'.' { $$= newToken("." ) } - +ELLIPSIS = '...' { $$= newToken("..." ) } - + +LPAREN = '(' { $$= newToken("(" ) } - +RPAREN = ')' { $$= newToken(")" ) } - +LBRACKET = '[' { $$= newToken("[" ) } - +RBRACKET = ']' { $$= newToken("]" ) } - +LCURLY = '{' { $$= newBegin( ) } - +RCURLY = '}' { $$= newEnd ( ) } - + +EQUAL = "==" { $$= newToken("==" ) } - +NOT_EQUAL = "!=" { $$= newToken("!=" ) } - +LTE = "<=" { $$= newToken("<=" ) } - +LT = "<" !'=' { $$= newToken("<" ) } - +GTE = ">=" { $$= newToken(">=" ) } - +GT = ">" !'=' { $$= newToken(">" ) } - + +DIV = '/' ![=*] { $$= newToken("/" ) } - +DIV_ASSIGN = "/=" { $$= newToken("/=" ) } - +PLUS = '+' ![+=] { $$= newToken("+" ) } - +PLUS_ASSIGN = "+=" { $$= newToken("+=" ) } - +INC = "++" { $$= newToken("++" ) } - +MINUS = '-' ![-=] { $$= newToken("-" ) } - +MINUS_ASSIGN = "-=" { $$= newToken("-=" ) } - +DEC = "--" { $$= newToken("--" ) } - +STAR = '*' !'=' { $$= newToken("*" ) } - +STAR_ASSIGN = "*=" { $$= newToken("*=" ) } - +MOD = '%' !'=' { $$= newToken("%" ) } - +MOD_ASSIGN = "%=" { $$= newToken("%=" ) } - +RSHIFT = ">>" !'=' { $$= newToken(">>" ) } - +RSHIFT_ASSIGN = ">>=" { $$= newToken(">>=" ) } - +LSHIFT = "<<" !'=' { $$= newToken("<<" ) } - +LSHIFT_ASSIGN = "<<=" { $$= newToken("<<=" ) } - + +LAND = "&&" { $$= newToken("&&" ) } - +LNOT = '!' !'=' { $$= newToken("!" ) } - +LOR = "||" { $$= newToken("||" ) } - + +BAND = '&' ![&=] { $$= newToken("&" ) } - +BAND_ASSIGN = "&=" { $$= newToken("&=" ) } - +BNOT = '~' { $$= newToken("~" ) } - +BOR = '|' ![|=] { $$= newToken("|" ) } - +BOR_ASSIGN = "|=" { $$= newToken("|=" ) } - +BXOR = '^' !'=' { $$= newToken("^" ) } - +BXOR_ASSIGN = "^=" { $$= newToken("^=" ) } - + +ALIGNOF = '__alignof__' !IDREST { $$= newToken("__alignof__" ) } - + | '__alignof' !IDREST { $$= newToken("__alignof" ) } - + +ASM = 'asm' !IDREST { $$= newToken("asm" ) } - + | '__asm' !IDREST { $$= newToken("__asm" ) } - + | '__asm__' !IDREST { $$= newToken("__asm__" ) } - + ATTRIBUTE = '__attribute__' !IDREST { $$= newToken("__attribute__") } - -AUTO = 'auto' !IDREST { $$= newToken("auto" ) } - -BOOL = '_Bool' !IDREST { $$= newToken("_Bool" ) } - -BREAK = 'break' !IDREST { $$= newToken("break" ) } - -CASE = 'case' !IDREST { $$= newToken("case" ) } - -CHAR = 'char' !IDREST { $$= newToken("char" ) } - -COMPLEX = '_Complex' !IDREST { $$= newToken("_Complex" ) } - - | '__complex__' !IDREST &{gnu} { $$= newToken("__complex__" ) } - -CONST = 'const' !IDREST { $$= newToken("const" ) } - - | '__const' !IDREST { $$= newToken("__const" ) } - -CONTINUE = 'continue' !IDREST { $$= newToken("continue" ) } - -DEFAULT = 'default' !IDREST { $$= newToken("default" ) } - -DO = 'do' !IDREST { $$= newToken("do" ) } - -DOUBLE = 'double' !IDREST { $$= newToken("double" ) } - -ELSE = 'else' !IDREST { $$= newToken("else" ) } - -ENUM = 'enum' !IDREST { $$= newToken("enum" ) } - -EXTERN = 'extern' !IDREST { $$= newToken("extern" ) } - -FLOAT = 'float' !IDREST { $$= newToken("float" ) } - -FOR = 'for' !IDREST { $$= newToken("for" ) } - -GOTO = 'goto' !IDREST { $$= newToken("goto" ) } - -IF = 'if' !IDREST { $$= newToken("if" ) } - -INLINE = 'inline' !IDREST { $$= newToken("inline" ) } - - | '__inline__' !IDREST &{gnu} { $$= newToken("__inline__" ) } - -INT = 'int' !IDREST { $$= newToken("int" ) } - -LONG = 'long' !IDREST { $$= newToken("long" ) } - -REGISTER = 'register' !IDREST { $$= newToken("register" ) } - -RESTRICT = 'restrict' !IDREST { $$= newToken("restrict" ) } - -RETURN = 'return' !IDREST { $$= newToken("return" ) } - -SHORT = 'short' !IDREST { $$= newToken("short" ) } - -SIGNED = 'signed' !IDREST { $$= newToken("signed" ) } - -SIZEOF = 'sizeof' !IDREST { $$= newToken("sizeof" ) } - -STATIC = 'static' !IDREST { $$= newToken("static" ) } - -STRUCT = 'struct' !IDREST { $$= newToken("struct" ) } - -SWITCH = 'switch' !IDREST { $$= newToken("switch" ) } - -TYPEDEF = 'typedef' !IDREST { $$= newToken("typedef" ) } - -TYPEOF = 'typeof' !IDREST { $$= newToken("typeof" ) } - - | '__typeof__' !IDREST { $$= newToken("__typeof__" ) } - -UNION = 'union' !IDREST { $$= newToken("union" ) } - -UNSIGNED = 'unsigned' !IDREST { $$= newToken("unsigned" ) } - -VOID = 'void' !IDREST { $$= newToken("void" ) } - -VOLATILE = 'volatile' !IDREST { $$= newToken("volatile" ) } - -WHILE = 'while' !IDREST { $$= newToken("while" ) } - - -IMAG = '__imag__' !IDREST &{gnu} { $$= newToken("__imag__" ) } - -LABEL = '__label__' !IDREST &{gnu} { $$= newToken("__label__") } - -REAL = '__real__' !IDREST &{gnu} { $$= newToken("__real__" ) } - +AUTO = 'auto' !IDREST { $$= newToken("auto" ) } - +BOOL = '_Bool' !IDREST { $$= newToken("_Bool" ) } - +BREAK = 'break' !IDREST { $$= newToken("break" ) } - +CASE = 'case' !IDREST { $$= newToken("case" ) } - +CHAR = 'char' !IDREST { $$= newToken("char" ) } - +COMPLEX = '_Complex' !IDREST { $$= newToken("_Complex" ) } - + | '__complex__' !IDREST &{gnu} { $$= newToken("__complex__" ) } - +CONST = 'const' !IDREST { $$= newToken("const" ) } - + | '__const' !IDREST { $$= newToken("__const" ) } - +CONTINUE = 'continue' !IDREST { $$= newToken("continue" ) } - +DEFAULT = 'default' !IDREST { $$= newToken("default" ) } - +DO = 'do' !IDREST { $$= newToken("do" ) } - +DOUBLE = 'double' !IDREST { $$= newToken("double" ) } - +ELSE = 'else' !IDREST { $$= newToken("else" ) } - +ENUM = 'enum' !IDREST { $$= newToken("enum" ) } - +EXTERN = 'extern' !IDREST { $$= newToken("extern" ) } - +FLOAT = 'float' !IDREST { $$= newToken("float" ) } - +FOR = 'for' !IDREST { $$= newToken("for" ) } - +GOTO = 'goto' !IDREST { $$= newToken("goto" ) } - +IF = 'if' !IDREST { $$= newToken("if" ) } - +INLINE = 'inline' !IDREST { $$= newToken("inline" ) } - + | '__inline__' !IDREST &{gnu} { $$= newToken("__inline__" ) } - +INT = 'int' !IDREST { $$= newToken("int" ) } - +LONG = 'long' !IDREST { $$= newToken("long" ) } - +REGISTER = 'register' !IDREST { $$= newToken("register" ) } - +RESTRICT = 'restrict' !IDREST { $$= newToken("restrict" ) } - +RETURN = 'return' !IDREST { $$= newToken("return" ) } - +SHORT = 'short' !IDREST { $$= newToken("short" ) } - +SIGNED = 'signed' !IDREST { $$= newToken("signed" ) } - +SIZEOF = 'sizeof' !IDREST { $$= newToken("sizeof" ) } - +STATIC = 'static' !IDREST { $$= newToken("static" ) } - +STRUCT = 'struct' !IDREST { $$= newToken("struct" ) } - +SWITCH = 'switch' !IDREST { $$= newToken("switch" ) } - +TYPEDEF = 'typedef' !IDREST { $$= newToken("typedef" ) } - +TYPEOF = 'typeof' !IDREST { $$= newToken("typeof" ) } - + | '__typeof__' !IDREST { $$= newToken("__typeof__" ) } - +UNION = 'union' !IDREST { $$= newToken("union" ) } - +UNSIGNED = 'unsigned' !IDREST { $$= newToken("unsigned" ) } - +VOID = 'void' !IDREST { $$= newToken("void" ) } - +VOLATILE = 'volatile' !IDREST { $$= newToken("volatile" ) } - +WHILE = 'while' !IDREST { $$= newToken("while" ) } - + +IMAG = '__imag__' !IDREST &{gnu} { $$= newToken("__imag__" ) } - +LABEL = '__label__' !IDREST &{gnu} { $$= newToken("__label__") } - +REAL = '__real__' !IDREST &{gnu} { $$= newToken("__real__" ) } - BUILTIN_VA_LIST = '__builtin_va_list' !IDREST &{gnu} { $$= newToken("__builtin_va_list" ) } - __RESTRICT = '__restrict' !IDREST &{gnu} { $$= newToken("__restrict" ) } - __INLINE = '__inline' !IDREST &{gnu} { $$= newToken("__inline" ) } - _FLOAT128 = '_Float128' !IDREST &{gnu} { $$= newToken("_Float128" ) } - +#--------------------------------------------- Meta grammar ----------------------------------------------# -#--------------------------------------------- Common rules ----------------------------------------------# +# the semicolon has to be explicit with no space eaten afterwards to prevent the +# input buffer from moving past it before redirecting input from the imported file -- = (blank | comment)* &{lang == META} - | < Space* > &{lang == C} { if (yyleng && $$) setComment($$, newComment(yytext)) } +metaCatch = META_AT ( META_LPAREN m:mexp { $$ = m } + | META_IMPORT s:META_STRING ";" { $$ = null; inputStackPush(get(s, String, value)) } + | META_LCB { $$ = null; lang= META } + ) + | &{ lang == META } - ( META_RCB { $$ = null; lang = C } + | s:meta_stmt { $$ = s } + ) +mexp = @{ lang = META } s:meta_exp META_RPAREN @{ lang = C } { $$= s } + | @{ lang = C } &{ 0 } + +meta_stmt = s:meta_block { $$ = s } + | META_SEMICOLON { $$ = null } + | l:META_IDENT p:meta_paramList e:meta_block { $$ = newFunc(l, p, e, null) } + | META_IF META_LPAREN c:meta_exp META_RPAREN t:meta_stmt META_ELSE f:meta_stmt { $$ = newIf(c, t, f ) } + | META_IF META_LPAREN c:meta_exp META_RPAREN t:meta_stmt { $$ = newIf(c, t, null) } + | META_WHILE META_LPAREN c:meta_exp META_RPAREN s:meta_stmt { $$ = newWhile(c, s) } + | META_DO s:meta_stmt META_WHILE META_LPAREN c:meta_exp META_RPAREN { $$ = newDo(s, c) } + | META_FOR META_LPAREN i:meta_ident META_IN e:meta_exp META_RPAREN s:meta_stmt { $$ = newForIn(i, e, s) } + | META_FOR META_LPAREN i:meta_stmt c:meta_stmt u:meta_exp META_RPAREN s:meta_stmt { $$ = newFor(i, c, u, s) } + | s:meta_switch { $$ = s } + | META_RETURN e:meta_exp { $$ = newReturn(e) } + | META_RETURN { $$ = newReturn(null) } + | META_BREAK { $$ = newBreak() } + | META_CONTINUE { $$ = newContinue() } + | META_THROW e:meta_exp { $$ = newUnary(Throw_proto, e) } + | t:meta_try { $$ = t } + | e:meta_exp META_SEMICOLON { $$ = e } + +meta_block = META_LCB m:meta_makeMap + ( s:meta_stmt { map_append(m, s) } + ) * + ( s:meta_exp { map_append(m, s) } + ) ? + META_RCB { $$ = newBlock(m) } -#| C rules -Space = Blank | Comment | EOL | Directive - | "__extension__" &{gnu} { icol += 13 } +meta_exp = META_VAR l:meta_ident META_ASSIGN e:meta_exp { $$ = newDeclaration(l, e) } +# | META_SYNTAX l:META_IDENT p:meta_paramList q:META_IDENT e:meta_block { $$ = (map_append(p, q), newFunc(l, p, e, makeInteger(2))) } +# | META_SYNTAX p:meta_paramList q:META_IDENT e:meta_block { $$ = (map_append(p, q), newFunc(null, p, e, makeInteger(2))) } +# | META_SYNTAX l:META_IDENT p:meta_paramList e:meta_block { $$ = newFunc(l, p, e, makeInteger(1)) } +# | META_SYNTAX p:meta_paramList e:meta_block { $$ = newFunc(null, p, e, makeInteger(1)) } + | l:META_IDENT o:meta_assignOp e:meta_exp { $$ = newAssign(Assign_proto, l, o, e) } + | l:meta_postfix META_DOT i:META_IDENT o:meta_assignOp e:meta_exp { $$ = newSetMap(SetMember_proto, l, i, o, e) } + | l:meta_postfix META_LBRAC i:meta_exp META_RBRAC o:meta_assignOp e:meta_exp { $$ = newSetMap(SetIndex_proto, l, i, o, e) } + | l:meta_syntax2 a:meta_argumentList s:meta_block { $$ = (map_append(a, s), apply(globals, globals, l, a, a)) } + | c:meta_cond { $$ = c } -Blank = ( [\003-\010] | '\013' | '\f' | [\016-\037] | [\177-\377] | ' ' ) { ++icol } - | '\t' { icol= (icol + 8) & ~7 } -EOL = ( "\r\n" | '\n' | '\r' ) { ++irow; icol= 0 } -Comment = "/*" ( !"*/" (EOL | Any) )* "*/" - | "//" ( ![\n\r] Any )* EOL +meta_ident = l:META_IDENT { $$ = l } +# | META_AT n:meta_prefix { $$ = newUnary(Unquote_proto, n) } -Directive = "#" (!EOL .)* +meta_syntax2 = < [a-zA-Z_][a-zA-Z0-9_]* > + &{ null != getSyntaxId(2, intern(yytext)) } - { $$ = getSyntaxId(2, intern(yytext)) } -Any = . { ++icol } +meta_try = META_TRY t:meta_stmt i:meta_null c:meta_null f:meta_null + ( META_CATCH META_LPAREN i:META_IDENT META_RPAREN c:meta_stmt ) ? + ( META_FINALLY f:meta_stmt ) ? { $$ = newTry(t, i, c, f) } -#| Meta rules -blank = space | eol -space = [ \t] -eol = ( "\n""\r"* - | "\r""\n"* - ) { inputStack->lineNumber++ } +meta_null = { $$ = null } -comment = "//" ( ![\n\r] . )* - | "/*" ( !"*/" (eol | .) )* "*/" +meta_assignOp = META_ASSIGN { $$= null } + | META_ASSIGNADD { $$= Add_symbol } + | META_ASSIGNSUB { $$= Sub_symbol } + | META_ASSIGNMUL { $$= Mul_symbol } + | META_ASSIGNDIV { $$= Div_symbol } + | META_ASSIGNMOD { $$= Mod_symbol } + | META_ASSIGNBITOR { $$= Bitor_symbol } + | META_ASSIGNBITXOR { $$= Bitxor_symbol } + | META_ASSIGNBITAND { $$= Bitand_symbol } + | META_ASSIGNSHLEFT { $$= Shleft_symbol } + | META_ASSIGNSHRIGHT { $$= Shright_symbol } + +meta_switch = META_SWITCH META_LPAREN e:meta_exp META_RPAREN + META_LCB statements:meta_makeMap labels:meta_makeMap + ( META_CASE l:meta_exp META_COLON { map_set(labels, eval(globals, l), makeInteger(map_size(statements))) } + | META_DEFAULT META_COLON { map_set(labels, __default___symbol, makeInteger(map_size(statements))) } + | s:meta_stmt { map_append(statements, s) } + )* + META_RCB { $$= newSwitch(e, labels, statements) } + +meta_cond = c:meta_logor META_QUERY t:meta_exp META_COLON f:meta_cond { $$ = newIf(c, t, f) } + | meta_logor + +meta_logor = l:meta_logand + ( META_LOGOR r:meta_logand { l = newBinary(Logor_proto, l, r) } + )* { $$ = l } + +meta_logand = l:meta_bitor + ( META_LOGAND r:meta_bitor { l = newBinary(Logand_proto, l, r) } + )* { $$ = l } + +meta_bitor = l:meta_bitxor + ( META_BITOR r:meta_bitxor { l = newBinary(Bitor_proto, l, r) } + )* { $$ = l } + +meta_bitxor = l:meta_bitand + ( META_BITXOR r:meta_bitand { l = newBinary(Bitxor_proto, l, r) } + )* { $$ = l } + +meta_bitand = l:meta_eq + ( META_BITAND r:meta_eq { l = newBinary(Bitand_proto, l, r) } + )* { $$ = l } + +meta_eq = l:meta_ineq + ( META_EQUAL r:meta_ineq { l = newBinary(Equal_proto, l, r) } + | META_NOTEQ r:meta_ineq { l = newBinary(Noteq_proto, l, r) } + )* { $$ = l } + +meta_ineq = l:meta_shift + ( META_LESS r:meta_shift { l = newBinary(Less_proto, l, r) } + | META_LESSEQ r:meta_shift { l = newBinary(Lesseq_proto, l, r) } + | META_GREATEREQ r:meta_shift { l = newBinary(Greatereq_proto, l, r) } + | META_GREATER r:meta_shift { l = newBinary(Greater_proto, l, r) } + )* { $$ = l } + +meta_shift = l:meta_sum + ( META_SHLEFT r:meta_sum { l = newBinary(Shleft_proto, l, r) } + | META_SHRIGHT r:meta_sum { l = newBinary(Shright_proto, l, r) } + )* { $$ = l } + +meta_sum = l:meta_prod + ( META_PLUS r:meta_prod { l = newBinary(Add_proto, l, r) } + | META_MINUS r:meta_prod { l = newBinary(Sub_proto, l, r) } + )* { $$ = l } + +meta_prod = l:meta_prefix + ( META_MULTI r:meta_prefix { l = newBinary(Mul_proto, l, r) } + | META_DIVIDE r:meta_prefix { l = newBinary(Div_proto, l, r) } + | META_MODULO r:meta_prefix { l = newBinary(Mod_proto, l, r) } + )* { $$ = l } + +meta_prefix = META_PLUS n:meta_prefix { $$= n } + | META_NEGATE n:meta_prefix { $$= newUnary(Neg_proto, n) } + | META_TILDE n:meta_prefix { $$= newUnary(Com_proto, n) } + | META_PLING n:meta_prefix { $$= newUnary(Not_proto, n) } + | META_PLUSPLUS n:meta_prefix { $$= newPreIncrement(n) } + | META_MINUSMINUS n:meta_prefix { $$= newPreDecrement(n) } +# | META_BACKTICK n:meta_prefix { $$ = newUnary(Quasiquote_proto, n) } +# | META_AT n:meta_prefix { $$ = newUnary(Unquote_proto, n) } + | n:meta_postfix { $$= n } + +meta_postfix = i:meta_value + ( META_DOT s:META_IDENT a:meta_argumentList { i = newInvoke(i, s, a) } + | META_DOT s:META_IDENT !meta_assignOp { i = newGetMap(GetMember_proto, i, s) } + | META_LBRAC p:meta_exp META_RBRAC !meta_assignOp { i = newGetMap(GetIndex_proto, i, p) } + | a:meta_argumentList { i = (null != getSyntax(1, i)) ? apply(globals, globals, getSyntax(1, i), a, i) : newCall(i, a) } + | META_PLUSPLUS { i = newPostIncrement(i) } + | META_MINUSMINUS { i = newPostDecrement(i) } + ) * { $$ = i } + +meta_paramList = META_LPAREN m:meta_makeMap + ( i:META_IDENT { map_append(m, i) } + ( META_COMMA i:META_IDENT { map_append(m, i) } + ) * + ) ? + META_RPAREN { $$ = m } -#--------------------------------------------- Meta grammar ----------------------------------------------# +meta_argumentList = META_LPAREN m:meta_makeMap + ( e:meta_exp { map_append(m, e) } + ( META_COMMA e:meta_exp { map_append(m, e) } + ) * + ) ? + META_RPAREN { $$ = m } -# the semicolon has to be explicit with no space eaten afterwards to prevent the -# input buffer from moving past it before redirecting input from the imported file -meta = META_IMPORT s:META_STRING ";" { $$ = null; inputStackPush(get(s, String, value)) } - | s:meta_stmt { $$ = s } - | !. { $$ = 0 } # signal end of current input file - -meta_stmt = s:meta_block { $$ = s } - | META_SEMICOLON { $$ = null } - | l:META_IDENT p:meta_paramList e:meta_block { $$ = newFunc(l, p, e, null) } - | META_IF META_LPAREN c:meta_exp META_RPAREN t:meta_stmt META_ELSE f:meta_stmt { $$ = newIf(c, t, f ) } - | META_IF META_LPAREN c:meta_exp META_RPAREN t:meta_stmt { $$ = newIf(c, t, null) } - | META_WHILE META_LPAREN c:meta_exp META_RPAREN s:meta_stmt { $$ = newWhile(c, s) } - | META_DO s:meta_stmt META_WHILE META_LPAREN c:meta_exp META_RPAREN { $$ = newDo(s, c) } - | META_FOR META_LPAREN i:meta_ident META_IN e:meta_exp META_RPAREN s:meta_stmt { $$ = newForIn(i, e, s) } - | META_FOR META_LPAREN i:meta_stmt c:meta_stmt u:meta_exp META_RPAREN s:meta_stmt { $$ = newFor(i, c, u, s) } - | s:meta_switch { $$ = s } - | META_RETURN e:meta_exp { $$ = newReturn(e) } - | META_RETURN { $$ = newReturn(null) } - | META_BREAK { $$ = newBreak() } - | META_CONTINUE { $$ = newContinue() } - | META_THROW e:meta_exp { $$ = newUnary(Throw_proto, e) } - | t:meta_try { $$ = t } - | e:meta_exp META_SEMICOLON { $$ = e } - -meta_block = META_LCB m:meta_makeMap - ( s:meta_stmt { map_append(m, s) } - ) * - ( s:meta_exp { map_append(m, s) } - ) ? - META_RCB { $$ = newBlock(m) } - -meta_exp = META_VAR l:meta_ident META_ASSIGN e:meta_exp { $$ = newDeclaration(l, e) } -# | META_SYNTAX l:META_IDENT p:meta_paramList q:META_IDENT e:meta_block { $$ = (map_append(p, q), newFunc(l, p, e, makeInteger(2))) } -# | META_SYNTAX p:meta_paramList q:META_IDENT e:meta_block { $$ = (map_append(p, q), newFunc(null, p, e, makeInteger(2))) } -# | META_SYNTAX l:META_IDENT p:meta_paramList e:meta_block { $$ = newFunc(l, p, e, makeInteger(1)) } -# | META_SYNTAX p:meta_paramList e:meta_block { $$ = newFunc(null, p, e, makeInteger(1)) } - | l:META_IDENT o:meta_assignOp e:meta_exp { $$ = newAssign(Assign_proto, l, o, e) } - | l:meta_postfix META_DOT i:META_IDENT o:meta_assignOp e:meta_exp { $$ = newSetMap(SetMember_proto, l, i, o, e) } - | l:meta_postfix META_LBRAC i:meta_exp META_RBRAC o:meta_assignOp e:meta_exp { $$ = newSetMap(SetIndex_proto, l, i, o, e) } - | l:meta_syntax2 a:meta_argumentList s:meta_block { $$ = (map_append(a, s), apply(globals, globals, l, a, a)) } - | c:meta_cond { $$ = c } - -meta_ident = l:META_IDENT { $$ = l } -# | META_AT n:meta_prefix { $$ = newUnary(Unquote_proto, n) } -meta_syntax2 = < [a-zA-Z_][a-zA-Z0-9_]* > - &{ null != getSyntaxId(2, intern(yytext)) } - { $$ = getSyntaxId(2, intern(yytext)) } +meta_value = META_BACKTICK - m:meta2c_statement { $$ = m } + | n:META_FLOAT { $$ = newFloat(n) } + | n:meta_integer { $$ = newInteger(n) } + | s:meta_string { $$ = newString(s) } + | s:meta_symbol { $$ = s } + | m:meta_map { $$ = newMap(m) } + | META_NULL { $$ = null } + | i:META_IDENT { $$ = newGetVariable(i) } + | p:meta_paramList e:meta_block { $$ = newFunc(null, p, e, null) } + | META_LPAREN ( i:meta_block | i:meta_exp ) META_RPAREN { $$ = i } -meta_try = META_TRY t:meta_stmt i:meta_null c:meta_null f:meta_null - ( META_CATCH META_LPAREN i:META_IDENT META_RPAREN c:meta_stmt ) ? - ( META_FINALLY f:meta_stmt ) ? { $$ = newTry(t, i, c, f) } +meta2c_statement = m:meta2c_expr { $$ = m } + | 'statement' { $$ = null } -meta_null = { $$ = null } +meta2c_expr = m:meta2c_constant { $$ = m } + | 'expression' { $$ = null } -meta_assignOp = META_ASSIGN { $$= null } - | META_ASSIGNADD { $$= Add_symbol } - | META_ASSIGNSUB { $$= Sub_symbol } - | META_ASSIGNMUL { $$= Mul_symbol } - | META_ASSIGNDIV { $$= Div_symbol } - | META_ASSIGNMOD { $$= Mod_symbol } - | META_ASSIGNBITOR { $$= Bitor_symbol } - | META_ASSIGNBITXOR { $$= Bitxor_symbol } - | META_ASSIGNBITAND { $$= Bitand_symbol } - | META_ASSIGNSHLEFT { $$= Shleft_symbol } - | META_ASSIGNSHRIGHT { $$= Shright_symbol } - -meta_switch = META_SWITCH META_LPAREN e:meta_exp META_RPAREN - META_LCB statements:meta_makeMap labels:meta_makeMap - ( META_CASE l:meta_exp META_COLON { map_set(labels, eval(globals, l), makeInteger(map_size(statements))) } - | META_DEFAULT META_COLON { map_set(labels, __default___symbol, makeInteger(map_size(statements))) } - | s:meta_stmt { map_append(statements, s) } - )* - META_RCB { $$= newSwitch(e, labels, statements) } - -meta_cond = c:meta_logor META_QUERY t:meta_exp META_COLON f:meta_cond { $$ = newIf(c, t, f) } - | meta_logor - -meta_logor = l:meta_logand - ( META_LOGOR r:meta_logand { l = newBinary(Logor_proto, l, r) } - )* { $$ = l } - -meta_logand = l:meta_bitor - ( META_LOGAND r:meta_bitor { l = newBinary(Logand_proto, l, r) } - )* { $$ = l } - -meta_bitor = l:meta_bitxor - ( META_BITOR r:meta_bitxor { l = newBinary(Bitor_proto, l, r) } - )* { $$ = l } - -meta_bitxor = l:meta_bitand - ( META_BITXOR r:meta_bitand { l = newBinary(Bitxor_proto, l, r) } - )* { $$ = l } - -meta_bitand = l:meta_eq - ( META_BITAND r:meta_eq { l = newBinary(Bitand_proto, l, r) } - )* { $$ = l } - -meta_eq = l:meta_ineq - ( META_EQUAL r:meta_ineq { l = newBinary(Equal_proto, l, r) } - | META_NOTEQ r:meta_ineq { l = newBinary(Noteq_proto, l, r) } - )* { $$ = l } - -meta_ineq = l:meta_shift - ( META_LESS r:meta_shift { l = newBinary(Less_proto, l, r) } - | META_LESSEQ r:meta_shift { l = newBinary(Lesseq_proto, l, r) } - | META_GREATEREQ r:meta_shift { l = newBinary(Greatereq_proto, l, r) } - | META_GREATER r:meta_shift { l = newBinary(Greater_proto, l, r) } - )* { $$ = l } - -meta_shift = l:meta_sum - ( META_SHLEFT r:meta_sum { l = newBinary(Shleft_proto, l, r) } - | META_SHRIGHT r:meta_sum { l = newBinary(Shright_proto, l, r) } - )* { $$ = l } - -meta_sum = l:meta_prod - ( META_PLUS r:meta_prod { l = newBinary(Add_proto, l, r) } - | META_MINUS r:meta_prod { l = newBinary(Sub_proto, l, r) } - )* { $$ = l } - -meta_prod = l:meta_prefix - ( META_MULTI r:meta_prefix { l = newBinary(Mul_proto, l, r) } - | META_DIVIDE r:meta_prefix { l = newBinary(Div_proto, l, r) } - | META_MODULO r:meta_prefix { l = newBinary(Mod_proto, l, r) } - )* { $$ = l } - -meta_prefix = META_PLUS n:meta_prefix { $$= n } - | META_NEGATE n:meta_prefix { $$= newUnary(Neg_proto, n) } - | META_TILDE n:meta_prefix { $$= newUnary(Com_proto, n) } - | META_PLING n:meta_prefix { $$= newUnary(Not_proto, n) } - | META_PLUSPLUS n:meta_prefix { $$= newPreIncrement(n) } - | META_MINUSMINUS n:meta_prefix { $$= newPreDecrement(n) } -# | META_BACKTICK n:meta_prefix { $$ = newUnary(Quasiquote_proto, n) } -# | META_AT n:meta_prefix { $$ = newUnary(Unquote_proto, n) } - | n:meta_postfix { $$= n } - -meta_postfix = i:meta_value ( META_DOT s:META_IDENT a:meta_argumentList { i = newInvoke(i, s, a) } - | META_DOT s:META_IDENT !meta_assignOp { i = newGetMap(GetMember_proto, i, s) } - | META_LBRAC p:meta_exp META_RBRAC !meta_assignOp { i = newGetMap(GetIndex_proto, i, p) } - | a:meta_argumentList { i = (null != getSyntax(1, i)) ? apply(globals, globals, getSyntax(1, i), a, i) : newCall(i, a) } - | META_PLUSPLUS { i = newPostIncrement(i) } - | META_MINUSMINUS { i = newPostDecrement(i) } - ) * { $$ = i } - -meta_paramList = META_LPAREN m:meta_makeMap - ( i:META_IDENT { map_append(m, i) } - ( META_COMMA i:META_IDENT { map_append(m, i) } - ) * - ) ? - META_RPAREN { $$ = m } - -meta_argumentList = META_LPAREN m:meta_makeMap - ( e:meta_exp { map_append(m, e) } - ( META_COMMA e:meta_exp { map_append(m, e) } - ) * - ) ? - META_RPAREN { $$ = m } +meta2c_constant = 'constant' - m:meta2c_value { $$ = m } -meta_value = n:META_FLOAT { $$ = newFloat(n) } - | n:meta_integer { $$ = newInteger(n) } - | s:meta_string { $$ = newString(s) } - | s:meta_symbol { $$ = s } - | m:meta_map { $$ = newMap(m) } - | META_NULL { $$ = null } - | i:META_IDENT { $$ = newGetVariable(i) } - | p:meta_paramList e:meta_block { $$ = newFunc(null, p, e, null) } - | META_LPAREN ( i:meta_block | i:meta_exp ) META_RPAREN { $$ = i } +meta2c_value = m:meta_makeMap { map_set(m, intern("__proto__"), intern("Token")) } < [0-9]+ > { map_set(m, intern("text"), makeString(unescape(yytext))) } { $$ = newMap(m) } -meta_string = s:META_STRING - { $$ = s } +meta_string = s:META_STRING - { $$ = s } -META_STRING = META_DQUOTE < (!META_DQUOTE meta_char)* > META_DQUOTE { $$ = makeString(unescape(yytext)) } +META_STRING = META_DQUOTE < (!META_DQUOTE meta_char)* > META_DQUOTE { $$ = makeString(unescape(yytext)) } -meta_char = '\\' . | . +meta_char = '\\' . | . -meta_symbol = META_HASH ( i:META_IDENT { $$ = newSymbol(i) } +meta_symbol = META_HASH + ( i:META_IDENT { $$ = newSymbol(i) } | i:meta_string { $$ = newSymbol(intern(get(i, String, value))) } ) -meta_map = META_LCB m:meta_makeMap - ( k:meta_key META_COLON v:meta_exp { map_set(m, k, v) } - ( META_COMMA k:meta_key META_COLON v:meta_exp { map_set(m, k, v) } - ) * - ) ? - META_RCB { $$ = m } - | META_LBRAC m:meta_makeMap - ( v:meta_exp { map_append(m, v) } - ( META_COMMA v:meta_exp { map_append(m, v) } - ) * - ) ? - META_RBRAC { $$ = m } +meta_map = META_LCB m:meta_makeMap + ( k:meta_key META_COLON v:meta_exp { map_set(m, k, v) } + ( META_COMMA k:meta_key META_COLON v:meta_exp { map_set(m, k, v) } + ) * + ) ? + META_RCB { $$ = m } + | META_LBRAC m:meta_makeMap + ( v:meta_exp { map_append(m, v) } + ( META_COMMA v:meta_exp { map_append(m, v) } + ) * + ) ? + META_RBRAC { $$ = m } meta_makeMap = { $$ = makeMap() } meta_key = META_IDENT | meta_integer -meta_keyword = META_SWITCH | META_CASE | META_DEFAULT | META_DO | META_FOR | META_IN | META_WHILE | META_IF | META_ELSE | META_NULL | META_RETURN | META_BREAK | META_CONTINUE - | META_THROW | META_TRY | META_CATCH | META_FINALLY -# | META_SYNTAX +meta_keyword = META_SWITCH | META_CASE | META_DEFAULT | META_DO | META_FOR | META_IN | META_WHILE | META_IF | META_ELSE | META_NULL | META_RETURN | META_BREAK | META_CONTINUE + | META_THROW | META_TRY | META_CATCH | META_FINALLY +# | META_SYNTAX -META_IDENT = !meta_keyword < [a-zA-Z_][a-zA-Z0-9_]* > - { $$ = intern(yytext) } +META_IDENT = !meta_keyword < [a-zA-Z_][a-zA-Z0-9_]* > - { $$ = intern(yytext) } -meta_integer = i:META_INTEGER { $$ = i } - | '-' i:meta_integer { $$ = makeInteger(-getInteger(i)) } +meta_integer = i:META_INTEGER { $$ = i } + | '-' i:meta_integer { $$ = makeInteger(-getInteger(i)) } -META_INTEGER = '0b' < [01]+ > - { $$ = makeInteger(strtol(yytext, 0, 2)) } - | '0x' < [0-9a-fA-F]+ > - { $$ = makeInteger(strtol(yytext, 0, 16)) } - | '0' < [0-7]+ > - { $$ = makeInteger(strtol(yytext, 0, 8)) } - | < [0-9]+ > - { $$ = makeInteger(strtol(yytext, 0, 10)) } - | META_SQUOTE < (!META_SQUOTE meta_char) > META_SQUOTE - { $$ = makeInteger(unescape(yytext)[0]) } +META_INTEGER = '0b' < [01]+ > - { $$ = makeInteger(strtol(yytext, 0, 2)) } + | '0x' < [0-9a-fA-F]+ > - { $$ = makeInteger(strtol(yytext, 0, 16)) } + | '0' < [0-7]+ > - { $$ = makeInteger(strtol(yytext, 0, 8)) } + | < [0-9]+ > - { $$ = makeInteger(strtol(yytext, 0, 10)) } + | META_SQUOTE < (!META_SQUOTE meta_char) > META_SQUOTE - { $$ = makeInteger(unescape(yytext)[0]) } -META_FLOAT = < [-+]* [0-9]+ '.' [0-9]* ('e'[-+]*[0-9]+)? > - { $$ = makeFloat(strtold(yytext, 0)) } - | < [-+]* [0-9]* '.' [0-9]+ ('e'[-+]*[0-9]+)? > - { $$ = makeFloat(strtold(yytext, 0)) } - | < [-+]* [0-9]+ ('e'[-+]*[0-9]+) > - { $$ = makeFloat(strtold(yytext, 0)) } +META_FLOAT = < [-+]* [0-9]+ '.' [0-9]* ('e'[-+]*[0-9]+)? > - { $$ = makeFloat(strtold(yytext, 0)) } + | < [-+]* [0-9]* '.' [0-9]+ ('e'[-+]*[0-9]+)? > - { $$ = makeFloat(strtold(yytext, 0)) } + | < [-+]* [0-9]+ ('e'[-+]*[0-9]+) > - { $$ = makeFloat(strtold(yytext, 0)) } -#META_FUN = 'fun' ![a-zA-Z0-9_] - -#META_SYNTAX = 'syntax' ![a-zA-Z0-9_] - +#META_FUN = 'fun' ![a-zA-Z0-9_] - +#META_SYNTAX = 'syntax' ![a-zA-Z0-9_] - META_VAR = 'var' ![a-zA-Z0-9_] - META_SWITCH = 'switch' ![a-zA-Z0-9_] - META_CASE = 'case' ![a-zA-Z0-9_] - @@ -2444,7 +2447,7 @@ META_COLON = ':' - META_SEMICOLON = ';' - META_COMMA = ',' - META_DOT = '.' - -#META_BACKTICK = '`' - +META_BACKTICK = '`' - META_AT = '@' - META_LCB = '{' - META_RCB = '}' - @@ -2455,6 +2458,38 @@ META_RPAREN = ')' - META_DQUOTE = '"' META_SQUOTE = "'" +#--------------------------------------------- Common rules ----------------------------------------------# + +- = (blank | comment)* &{lang == META} + | < Space* > &{lang == C} { if (yyleng && $$) setComment($$, newComment(yytext)) } + + +#| C rules +Space = Blank | Comment | EOL | Directive + | "__extension__" &{gnu} { icol += 13 } + +Blank = ( [\003-\010] | '\013' | '\f' | [\016-\037] | [\177-\377] | ' ' ) { ++icol } + | '\t' { icol= (icol + 8) & ~7 } + +EOL = ( "\r\n" | '\n' | '\r' ) { ++irow; icol= 0 } + +Comment = "/*" ( !"*/" (EOL | Any) )* "*/" + | "//" ( ![\n\r] Any )* EOL + +Directive = "#" (!EOL .)* + +Any = . { ++icol } + +#| Meta rules +blank = space | eol +space = [ \t] +eol = ( "\n""\r"* + | "\r""\n"* + ) { inputStack->lineNumber++ } + +comment = "//" ( ![\n\r] . )* + | "/*" ( !"*/" (eol | .) )* "*/" + %% ; @@ -2739,22 +2774,22 @@ oop apply(oop scope, oop this, oop func, oop args, oop ast) switch (jbt) { case j_return: { untrace(ast); - delScope(localScope); + delScope(localScope); oop result = jbs->result; jbRecPop(); return result; } case j_break: { - delScope(localScope); + delScope(localScope); runtimeError("break outside of a loop or switch"); } case j_continue: { - delScope(localScope); + delScope(localScope); runtimeError("continue outside of a loop"); } case j_throw: { untrace(ast); - delScope(localScope); + delScope(localScope); oop res= jbs->result; jbRecPop(); jbs->result= res; @@ -3900,7 +3935,7 @@ void outputNode(oop node) } #if 0 while (orow < node->row) { printf("\n"); ++orow; ocol= 0; } - while (ocol < node->col) { printf(" " ); ++ocol; } + while (ocol < node->col) { printf(" " ); ++ocol; } #endif outputNode(map_get(node, comment_symbol)); } @@ -4625,10 +4660,10 @@ int main(int argc, char **argv) } if (opt_g) { - if (nalloc < 1024) printf("[GC: %lli bytes allocated]\n", nalloc ); - else if (nalloc < 1024*1024) printf("[GC: %lli kB allocated]\n", nalloc / 1024 ); - else if (nalloc < 1024*1024*1024) printf("[GC: %.2f MB allocated]\n", (double)nalloc / ( 1024*1024)); - else printf("[GC: %.2f GB allocated]\n", (double)nalloc / (1024*1024*1024)); + if (nalloc < 1024) printf("[GC: %lli bytes allocated]\n", nalloc ); + else if (nalloc < 1024*1024) printf("[GC: %lli kB allocated]\n", nalloc / 1024 ); + else if (nalloc < 1024*1024*1024) printf("[GC: %.2f MB allocated]\n", (double)nalloc / ( 1024*1024)); + else printf("[GC: %.2f GB allocated]\n", (double)nalloc / (1024*1024*1024)); }