diff options
Diffstat (limited to 'grammars/c/grammar.earlpy')
-rw-r--r-- | grammars/c/grammar.earlpy | 265 |
1 files changed, 265 insertions, 0 deletions
diff --git a/grammars/c/grammar.earlpy b/grammars/c/grammar.earlpy new file mode 100644 index 0000000..99cafe9 --- /dev/null +++ b/grammars/c/grammar.earlpy @@ -0,0 +1,265 @@ +#### OPTIMIZATIONS: +# where possible, we want parse trees that look like: +# (((A + B) + C) + D), i.e., left-associativity because it avoids long chains +# of completions. Another explanation for it is that then ambiguity is resolved +# as early in the left-to-right parse as possible. + +KEYWORDS list + switch volatile case while do else const for if + struct union typedef void return break continue + sizeof + +IDENT regex + [a-zA-Z_][0-9a-zA-Z_]* + +INT regex + ((0x[0-9a-fA-F]*)|([0-9]*))([uUlL])* + +# https://stackoverflow.com/questions/2039795/regular-expression-for-a-string-literal-in-flex-lex +STRING regex + ["]([^\\"]|\\.)*["] + +CHAR regex + [']([\\][']|[^'][^'])*[^']?['] + +OP list + ; , + - + ! % * & / << >> ^ | + -= += != %= *= &= /= <<= == >>= ^= |= + && || ++ -- + < <= > >= = + . -> + +TERNARY list + : ? + +PARENS list + ( ) { } [ ] + +############### ERROR RECOVERY +# These rules match either a single token, or a pair of balanced parentheses + +NONPAREN nonterm + KEYWORDS + IDENT + INT + STRING + CHAR + TERNARY + OP + +ERROR_INNER nonterm .poison + ERROR + ERROR_INNER ERROR + +ERROR nonterm .poison + ( ERROR_INNER ) + { ERROR_INNER } + [ ERROR_INNER ] + ( ) + { } + [ ] + NONPAREN + +############### TYPE PARSING +# A PRIMITIVE_TYPE is the core object that takes up space after dereferencing, +# calling, etc. A normal variable declaration is PRIMITIVE_TYPE (expression) +PRIMITIVE_TYPE nonterm + struct IDENT + union IDENT + struct IDENT AGGREGATE_DECLARATION + union IDENT AGGREGATE_DECLARATION + const PRIMITIVE_TYPE + volatile PRIMITIVE_TYPE + void + IDENT + +# A TYPE_EXPRESSION is basically an lvalue expression. +TYPE_EXPRESSION nonterm + IDENT + TYPE_EXPRESSION [ ] + TYPE_EXPRESSION [ EXPR ] + * TYPE_EXPRESSION + const TYPE_EXPRESSION + ( TYPE_EXPRESSION ) + TYPE_EXPRESSION ( ) + TYPE_EXPRESSION ( ARGS ) + +DECLARATION nonterm + PRIMITIVE_TYPE TYPE_EXPRESSION + +# An ANONYMOUS_TYPE has no name +ANONYMOUS_TYPE nonterm + PRIMITIVE_TYPE + ANONYMOUS_TYPE [ ] + ANONYMOUS_TYPE [ EXPR ] + ANONYMOUS_TYPE * + ANONYMOUS_TYPE const * + const ANONYMOUS_TYPE + ( ANONYMOUS_TYPE ) + ANONYMOUS_TYPE ( ) + ANONYMOUS_TYPE ( ARGS ) + +############### TOP LEVEL +TOP_LEVEL nonterm .start + TOP_LEVEL TYPEDEF + TOP_LEVEL STRUCTDECL + TOP_LEVEL FUNCTION + TOP_LEVEL DECLARATION_STATEMENT + TYPEDEF + STRUCTDECL + FUNCTION + DECLARATION_STATEMENT + TOP_LEVEL ERROR + ERROR + +ARGS nonterm + ANONYMOUS_TYPE + ARGS , ANONYMOUS_TYPE + DECLARATION + ARGS , DECLARATION + +CALL_ARGS nonterm + CALL_ARGS , EXPR + EXPR + +OLD_ARGS nonterm + OLD_ARGS , IDENT + IDENT + +OLD_ARG_DECLS nonterm + OLD_ARG_DECLS DECLARATION_STATEMENT + DECLARATION_STATEMENT + +FUNCTION nonterm + DECLARATION ( ) TRUE_BLOCK + DECLARATION ( ARGS ) TRUE_BLOCK + DECLARATION ( OLD_ARGS ) OLD_ARG_DECLS TRUE_BLOCK + IDENT ( OLD_ARGS ) OLD_ARG_DECLS TRUE_BLOCK + +AGGREGATE_DECLARATION nonterm + { STMTS } + { } + +TYPEDEF nonterm + typedef PRIMITIVE_TYPE TYPE_EXPRESSION ; + +STRUCTDECL nonterm + struct IDENT AGGREGATE_DECLARATION ; + +UNIONDECL nonterm + union IDENT AGGREGATE_DECLARATION ; + +EXPR nonterm + INT + STRING + CHAR + IDENT + EXPR -- + EXPR ++ + -- EXPR + ++ EXPR + - EXPR + + EXPR + & EXPR + * EXPR + ( ANONYMOUS_TYPE ) EXPR + EXPR ( ) + EXPR ( CALL_ARGS ) + EXPR OP EXPR + EXPR ? EXPR : EXPR + EXPR ? : EXPR + EXPR [ EXPR ] + ! EXPR + ( EXPR ) + sizeof EXPR + sizeof ANONYMOUS_TYPE + INITIALIZER_LIST + EXPR EXPR + +INITIALIZER_LIST nonterm + { INNER_INITIALIZER_LIST } + { } + +INNER_INITIALIZER_LIST nonterm + EXPR + INNER_INITIALIZER_LIST , EXPR + INNER_INITIALIZER_LIST , + +IF nonterm + if ( EXPR ) BLOCK + if ( EXPR ) BLOCK else BLOCK + +WHILE nonterm + while ( EXPR ) BLOCK + +DO nonterm + do BLOCK while ( EXPR ) + +FOR nonterm + for ( ; ; ) BLOCK + for ( ; ; EXPR ) BLOCK + for ( ; EXPR ; ) BLOCK + for ( ; EXPR ; EXPR ) BLOCK + for ( EXPR ; ; ) BLOCK + for ( EXPR ; ; EXPR ) BLOCK + for ( EXPR ; EXPR ; ) BLOCK + for ( EXPR ; EXPR ; EXPR ) BLOCK + +SWITCH nonterm + switch ( EXPR ) BLOCK + +DECLARATION_CHAIN nonterm + DECLARATION_CHAIN , TYPE_EXPRESSION + TYPE_EXPRESSION + DECLARATION_CHAIN , TYPE_EXPRESSION = EXPR + TYPE_EXPRESSION = EXPR + +DECLARATION_STATEMENT nonterm + PRIMITIVE_TYPE DECLARATION_CHAIN ; + +RETURN nonterm + return EXPR ; + return ; + +BREAK nonterm + break ; + +CONTINUE nonterm + continue ; + +LABEL nonterm + IDENT : STMT + +CASE nonterm + case EXPR : STMT + +STMT nonterm + TRUE_BLOCK + LABEL + CASE + BREAK + CONTINUE + RETURN + IF + WHILE + DO + FOR + SWITCH + DECLARATION_STATEMENT + EXPR ; + ; + +STMTS nonterm + STMTS STMT + STMT + STMTS ERROR + ERROR + +TRUE_BLOCK nonterm + { } + { STMTS } + +BLOCK nonterm + TRUE_BLOCK + STMT |