%token _return_ "return"
 %token _return__ "!return"
 %token _super_ "super"
-%token _super__ "!super"
 %token _switch_ "switch"
 %token _this_ "this"
 %token _throw_ "throw"
     | "return" { $$ = CYNew CYWord("return"); }
     | "!return" { $$ = CYNew CYWord("return"); }
     | "super" { $$ = CYNew CYWord("super"); }
-    | "!super" { $$ = CYNew CYWord("super"); }
     | "switch" { $$ = CYNew CYWord("switch"); }
     | "this" { $$ = CYNew CYWord("this"); }
     | "throw" { $$ = CYNew CYWord("throw"); }
     ;
 
 SuperProperty
-    : LexSetRegExp "!super" "[" Expression "]" { $$ = CYNew CYSuperAccess($4); }
-    | LexSetRegExp "!super" "." IdentifierName { $$ = CYNew CYSuperAccess(CYNew CYString($4)); }
+    : LexSetRegExp "super" { if (!driver.super_.top()) CYERR(@2, "invalid super"); } "[" Expression "]" { $$ = CYNew CYSuperAccess($5); }
+    | LexSetRegExp "super" { if (!driver.super_.top()) CYERR(@2, "invalid super"); } "." IdentifierName { $$ = CYNew CYSuperAccess(CYNew CYString($5)); }
     ;
 
 MetaProperty
     ;
 
 SuperCall
-    : LexSetRegExp "!super" Arguments { $$ = CYNew CYSuperCall($3); }
+    : LexSetRegExp "super" { if (!driver.super_.top()) CYERR(@2, "invalid super"); } Arguments { $$ = CYNew CYSuperCall($4); }
     ;
 
 Arguments
 
 MessageExpression
     : "[" LexPushInOff AssignmentExpressionClassic { driver.contexts_.push_back($3); } SelectorList "]" LexPopIn { driver.contexts_.pop_back(); } { $$ = CYNew CYSendDirect($3, $5); }
-    | "[" LexPushInOff LexSetRegExp "!super" { driver.context_ = NULL; } SelectorList "]" LexPopIn { $$ = CYNew CYSendSuper($6); }
+    | "[" LexPushInOff LexSetRegExp "super" { driver.context_ = NULL; } SelectorList "]" LexPopIn { $$ = CYNew CYSendSuper($6); }
     ;
 
 SelectorExpression_
 
 "set"             L /*III*/ F(tk::_set_, hi::Meta);
 "short"           L /*FII*/ F(tk::_short_, hi::Type);
 "static"          L /*FS?*/ F(tk::_static_, hi::Meta);
-"super"           L /*FFK*/ F(yyextra->super_.top() ? tk::_super__ : tk::_super_, hi::Constant);
+"super"           L /*FFK*/ F(tk::_super_, hi::Constant);
 "switch"          L /*KKK*/ F(tk::_switch_, hi::Control);
 "synchronized"    L /*FII*/ F(tk::_synchronized_, hi::Meta);
 "this"            L /*KKK*/ F(tk::_this_, hi::Constant);