--- /dev/null
+/* -------------------------------------------------------
+ The Grammar
+ ------------------------------------------------------- */
+/*
+ * added tokens
+ * Pipe '|'
+ * Lparen '('
+ * Rparen ')'
+ * Lessthan '<'
+ * Greaterthan '<'
+ * Ampersand '&'
+ * Semicolon ';'
+ */
+%start_symbol complete_command
+%token_prefix TOKEN_
+%token_type {struct token *}
+%extra_argument { struct parser_state *pstate }
+%include {
+#include "parser.h"
+#include <assert.h>
+}
+
+complete_command ::= list separator.
+complete_command ::= list.
+
+list ::= list separator_op and_or.
+list ::= and_or.
+
+and_or ::= pipeline.
+and_or ::= and_or AND_IF linebreak pipeline.
+and_or ::= and_or OR_IF linebreak pipeline.
+
+pipeline ::= pipe_sequence.
+pipeline ::= Bang pipe_sequence.
+
+pipe_sequence ::= command.
+pipe_sequence ::= pipe_sequence Pipe linebreak command.
+
+command ::= simple_command.
+command ::= compound_command.
+command ::= compound_command redirect_list.
+command ::= function_definition.
+
+compound_command ::= brace_group.
+compound_command ::= subshell.
+compound_command ::= for_clause.
+compound_command ::= case_clause.
+compound_command ::= if_clause.
+compound_command ::= while_clause.
+compound_command ::= until_clause.
+
+subshell ::= Lparen compound_list Rparen.
+
+compound_list ::= term. [NEWLINE]
+compound_list ::= newline_list term. [NEWLINE]
+compound_list ::= term separator.
+compound_list ::= newline_list term separator.
+
+term ::= term separator and_or.
+term ::= and_or.
+
+for_clause ::= For name linebreak do_group.
+for_clause ::= For name linebreak in sequential_sep do_group.
+for_clause ::= For name linebreak in wordlist sequential_sep do_group.
+
+name ::= NAME /* Apply rule 5 */.
+
+in ::= In /* Apply rule 6 */.
+ /* TODO start looking for pattern = Esac here */
+
+wordlist ::= wordlist WORD.
+wordlist ::= WORD.
+
+%fallback WORD
+ NAME Esac In
+.
+
+case_clause ::= case_start case_list Esac.
+case_clause ::= case_start Esac. { pstate->incase = 0; }
+
+/* added to simplify */
+case_start ::= Case WORD linebreak in linebreak.
+
+case_list ::= case_list case_item.
+case_list ::= case_item.
+
+%left NEWLINE.
+%right DSEMI.
+%right WORD.
+
+//%left WORD.
+
+case_item ::= case_item_ns .
+//case_item ::= case_item_ns DSEMI linebreak.
+
+case_item_ns ::= pattern Rparen linebreak. [DSEMI]
+case_item_ns ::= pattern Rparen linebreak DSEMI linebreak.
+
+case_item_ns ::= pattern Rparen compound_list linebreak. [DSEMI]
+case_item_ns ::= pattern Rparen compound_list linebreak DSEMI linebreak.
+//case_item_ns ::= Lparen pattern Rparen linebreak. [DSEMI]
+//case_item_ns ::= Lparen pattern Rparen compound_list linebreak. [DSEMI]
+
+//case_item_end ::= linebreak.
+//case_item_end ::= linebreak DSEMI linebreak.
+
+/* rule four implicitly done via %fallback */
+pattern ::= WORD . /* Apply rule 4 */
+pattern ::= pattern Pipe WORD . /* Do not apply rule 4 */
+
+%ifdef CASE_NS
+case_clause ::= case_start case_list_ns Esac.
+
+case_list_ns ::= case_list case_item_ns.
+case_list_ns ::= case_item_ns.
+
+%endif
+
+if_clause ::= If compound_list Then compound_list else_part Fi.
+if_clause ::= If compound_list Then compound_list Fi.
+
+else_part ::= Elif compound_list Then compound_list.
+else_part ::= Elif compound_list Then compound_list else_part.
+else_part ::= Else compound_list.
+
+while_clause ::= While compound_list do_group.
+
+until_clause ::= Until compound_list do_group.
+
+//function_definition ::= fname Lparen Rparen linebreak function_body.
+function_definition ::= WORD Lparen Rparen linebreak function_body.
+
+function_body ::= compound_command /* Apply rule 9 */.
+function_body ::= compound_command redirect_list /* Apply rule 9 */.
+
+/* we would need two tokens of look-ahead to prove this should be a name
+ * and not a word
+ */
+//fname ::= NAME /* Apply rule 8 */.
+//fname ::= WORD.
+
+brace_group ::= Lbrace compound_list Rbrace.
+
+do_group ::= Do compound_list Done /* Apply rule 6 */.
+
+simple_command ::= cmd_prefix cmd_word cmd_suffix.
+simple_command ::= cmd_prefix cmd_word.
+simple_command ::= cmd_prefix.
+simple_command ::= cmd_name cmd_suffix.
+simple_command ::= cmd_name.
+
+cmd_name ::= WORD /* Apply rule 7a */.
+
+cmd_word ::= WORD /* Apply rule 7b */.
+
+cmd_prefix ::= io_redirect.
+cmd_prefix ::= cmd_prefix io_redirect.
+cmd_prefix ::= ASSIGNMENT_WORD.
+cmd_prefix ::= cmd_prefix ASSIGNMENT_WORD.
+
+cmd_suffix ::= io_redirect.
+cmd_suffix ::= cmd_suffix io_redirect.
+cmd_suffix ::= WORD.
+cmd_suffix ::= cmd_suffix WORD.
+
+redirect_list ::= io_redirect.
+redirect_list ::= redirect_list io_redirect.
+
+io_redirect ::= io_file.
+io_redirect ::= IO_NUMBER io_file.
+io_redirect ::= io_here.
+io_redirect ::= IO_NUMBER io_here.
+
+io_file ::= Lessthan filename.
+io_file ::= LESSAND filename.
+io_file ::= Greaterthan filename.
+io_file ::= GREATAND filename.
+io_file ::= DGREAT filename.
+io_file ::= LESSGREAT filename.
+io_file ::= CLOBBER filename.
+
+filename ::= WORD /* Apply rule 2 */.
+
+io_here ::= DLESS here_end.
+io_here ::= DLESSDASH here_end.
+
+here_end ::= WORD /* Apply rule 3 */.
+
+newline_list ::= newline_list NEWLINE.
+newline_list ::= NEWLINE. { pstate->linebreak = 1; }
+
+linebreak ::= newline_list. [NEWLINE]
+linebreak ::= /* empty */. [NEWLINE]
+
+separator_op ::= Ampersand.
+separator_op ::= Semicolon.
+
+separator ::= separator_op linebreak. [NEWLINE]
+separator ::= newline_list. [NEWLINE]
+
+sequential_sep ::= Semicolon linebreak.
+sequential_sep ::= newline_list.