summaryrefslogtreecommitdiff
path: root/grammars/c/grammar.earlpy
diff options
context:
space:
mode:
Diffstat (limited to 'grammars/c/grammar.earlpy')
-rw-r--r--grammars/c/grammar.earlpy265
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
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback