CYOptions options;
     CYOutput output(*str.rdbuf(), options);
     output.pretty_ = true;
-    (new(pool) CYExternal(new(pool) CYString("C"), typed))->Output(output, CYNoFlags);
+    (new(pool) CYExternalExpression(new(pool) CYString("C"), typed))->Output(output, CYNoFlags);
     return CYCastJSValue(context, CYJSString(str.str()));
 } CYCatch(NULL) }
 
     std::stringbuf out;
     CYOptions options;
     CYOutput output(out, options);
+    output.pretty_ = true;
     (new(pool) CYTypeExpression(CYDecodeType(pool, internal->type_->Copy(pool, ""))))->Output(output, CYNoFlags);
     return CYCastJSValue(context, CYJSString(out.str().c_str()));
 } CYCatch(NULL) }
 
     out << ' ' << object_;
 }
 
-void CYExternal::Output(CYOutput &out, CYFlags flags) const {
+void CYExternalDefinition::Output(CYOutput &out, CYFlags flags) const {
     out << "extern" << ' ' << abi_ << ' ' << typed_;
     out.Terminate();
 }
 
+void CYExternalExpression::Output(CYOutput &out, CYFlags flags) const {
+    out << '(' << "extern" << ' ' << abi_ << ' ' << typed_ << ')';
+}
+
 void CYFatArrow::Output(CYOutput &out, CYFlags flags) const {
     out << '(' << parameters_ << ')' << ' ' << "=>" << ' ' << '{' << code_ << '}';
 }
 
     ;
 
 ExternCStatement
-    : TypedIdentifierField[typed] TerminatorHard { $$ = CYNew CYExternal(CYNew CYString("C"), $typed); }
+    : TypedIdentifierField[typed] TerminatorHard { $$ = CYNew CYExternalDefinition(CYNew CYString("C"), $typed); }
     | TypeDefinition[pass] { $$ = $pass; }
     ;
 
     | ExternCStatement[pass] { $$ = $pass; }
     ;
 
+ABI
+    : StringLiteral[abi] { if (strcmp($abi->Value(), "C") != 0) CYERR(@abi, "unknown extern binding"); }
+    ;
+
 Statement__
-    : "extern" NewLineNot StringLiteral[abi] { if (strcmp($abi->Value(), "C") != 0) CYERR(@abi, "unknown extern binding"); } ExternC[pass] { $$ = $pass; }
+    : "extern" NewLineNot ABI[abi] ExternC[pass] { $$ = $pass; }
+    ;
+
+PrimaryExpression
+    : "(" LexOf "extern" NewLineOpt ABI[abi] TypedIdentifierField[typed] ")" { $$ = CYNew CYExternalExpression(CYNew CYString("C"), $typed); }
     ;
 /* }}} */
 @end
 
     return object_.Replace(context, lhs_);
 }
 
-CYStatement *CYExternal::Replace(CYContext &context) {
-    return $E($ CYAssign($V(typed_->identifier_), $C1(typed_->Replace(context), $C2($V("dlsym"), $V("RTLD_DEFAULT"), $S(typed_->identifier_->Word())))));
+CYStatement *CYExternalDefinition::Replace(CYContext &context) {
+    return $E($ CYAssign($V(typed_->identifier_), $ CYExternalExpression(abi_, typed_)));
+}
+
+CYTarget *CYExternalExpression::Replace(CYContext &context) {
+    return $C1(typed_->Replace(context), $C2($V("dlsym"), $V("RTLD_DEFAULT"), $S(typed_->identifier_->Word())));
 }
 
 CYNumber *CYFalse::Number(CYContext &context) {
 
     virtual void Output(CYOutput &out, CYFlags flags) const;
 };
 
-struct CYExternal :
+struct CYExternalExpression :
+    CYTarget
+{
+    CYString *abi_;
+    CYTypedIdentifier *typed_;
+
+    CYExternalExpression(CYString *abi, CYTypedIdentifier *typed) :
+        abi_(abi),
+        typed_(typed)
+    {
+    }
+
+    CYPrecedence(0)
+
+    virtual CYTarget *Replace(CYContext &context);
+    virtual void Output(CYOutput &out, CYFlags flags) const;
+};
+
+struct CYExternalDefinition :
     CYStatement
 {
     CYString *abi_;
     CYTypedIdentifier *typed_;
 
-    CYExternal(CYString *abi, CYTypedIdentifier *typed) :
+    CYExternalDefinition(CYString *abi, CYTypedIdentifier *typed) :
         abi_(abi),
         typed_(typed)
     {