/* * * Copyright 2001-2002 by the Regents of the University of California. * All rights reserved. * * HARMONIA: Ladle2 description for C * * RCS Info: $Revision: 1.1 $ on $Date: 2003/05/12 01:49:33 $ * $Source: /home/cs/harmonia/cvsroot/www/harmonia/projects/langs/c/c.ldl,v $ */ %whitespace WSPC %comment COMMENT %token AUTO REGISTER STATIC cEXTERN TYPEDEF CONST \ VOLATILE STRUCT UNION ENUM CASE DEFAULT \ IF SWITCH WHILE DO FOR GOTO CONTINUE BREAK \ RETURN SIZEOF %token CLANGCHAR CLANGSHORT CLANGINT CLANGLONG CLANGFLOAT \ DOUBLE SIGNED UNSIGNED VOID /* New C99 keywords */ %token INLINE RESTRICT %token _BOOL _COMPLEX _IMAGINARY %token INT_CONST INT_CONST_U INT_CONST_L INT_CONST_UL \ INT_CONST_LL INT_CONST_ULL %token FLOAT_CONST DOUBLE_CONST LONGDOUBLE_CONST %token STR_CONST WIDE_STR_CONST %token CHAR_CONST WIDE_CHAR_CONST %token IDSYM %token COMMA { alias ',' } \ SEMI { alias ';' } \ LBRACE { alias '{' } \ RBRACE { alias '}' } \ RBRACK { alias ']' } \ ELLIPSIS %token PREPROC /* Low precedence */ %nonassoc BARE_IF_PREC %nonassoc ELSE %right COMMA_PREC %right ASSIGN { alias '=' } \ MULASSIGN \ DIVASSIGN \ MODASSIGN \ ADDASSIGN \ SUBASSIGN \ SHLASSIGN \ SHRASSIGN \ ANDASSIGN \ XORASSIGN \ ORASSIGN %right QUESTION { alias '?' } COLON { alias ':' } %left LOR %left LAND %left BOR { alias '|' } %left BXOR { alias '^' } %left BAND { alias '&' } %left EQ NE %left LE LT { alias '<' } \ GE GT { alias '>' } %left LSHIFT RSHIFT %left MINUS { alias '-' } PLUS { alias '+' } %left TIMES { alias '*' } DIV { alias '/' } \ MOD { alias '%' } %nonassoc CAST %left BNOT { alias '~' } NOT { alias '!' } UNARY %left INC DEC DOT { alias '.' } PTR \ LBRACK { alias '[' } POSTFIX %left LPAREN { alias '(' } RPAREN { alias ')' } /* High precedence */ %% /* Note the following abbreviations: spec -> specifier decl -> declaration declr -> declarator */ trans_unit: /* GCC effectively has * rather than + here */ ext_decls:(ext_decl:ext_decl)+ => "TranslationUnit" ; ext_decl : specs:(spec:decl_spec)+ declr:declr decls:(decl:decl)* body:comp_stmt => "FunctionDefinition" | decl:decl => "OtherExtDeclaration" | p:PREPROC => "PreprocessorJunk" ; decl_spec : spec:stor_class_spec => "StorageDeclSpec" | spec:type_spec => "TypeSpecDeclSpec" | qual:type_qual => "TypeQualDeclSpec" | qual:INLINE /* C99 */ => "FunctionQualDeclSpec" ; decl : specs:(spec:decl_spec)+ declrs:(declr:init_declr)*[','] semi:';' => "Declaration" ; stor_class_spec : s:AUTO => "AutoStrClassSpec" | s:REGISTER => "RegisterStrClassSpec" | s:STATIC => "StaticStrClassSpec" | s:cEXTERN => "ExternStrClassSpec" | s:TYPEDEF => "TypedefStrClassSpec" ; type_name : spec_quals:(spec_qual:type_spec_qual)+ declr:(declr:abst_declr)? => "TypeName" ; type_spec_qual : spec:type_spec => "TypeSpecifier" | qual:type_qual => "TypeQualifier" ; type_spec : t:VOID => "VoidTypeSpec" | t:CLANGCHAR => "CharTypeSpec" | t:CLANGSHORT => "ShortTypeSpec" | t:CLANGINT => "IntTypeSpec" | t:CLANGLONG => "LongTypeSpec" | t:CLANGFLOAT => "FloatTypeSpec" | t:DOUBLE => "DoubleTypeSpec" | t:SIGNED => "SignedTypeSpec" | t:UNSIGNED => "UnsignedTypeSpec" | t:_BOOL => "BooleanTypeSpec" /* C99 */ | t:_COMPLEX => "ComplexTypeSpec" /* C99 */ | t:_IMAGINARY => "ImaginaryTypeSpec" /* C99 */ | kw:STRUCT name:(name:IDSYM)? l:'{' decls:(decl:struct_decl)+ r:'}' => "StructDefinitionSpec" | kw:UNION name:(name:IDSYM)? l:'{' decls:(decl:struct_decl)+ r:'}' => "UnionDefinitionSpec" | kw:STRUCT name:IDSYM => "StructReferenceSpec" | kw:UNION name:IDSYM => "UnionReferenceSpec" | kw:ENUM name:(name:IDSYM)? l:'{' enums:(enum_:enum_)+[','] c:(c:',')? r:'}' /* The optional comma is only in C99 ^ */ => "DefinedEnumSpec" | kw:ENUM name:IDSYM => "ReferencedEnumSpec" | type_name:IDSYM => "TypedefTypeSpec" ; type_qual : q:CONST => "ConstTypeQualifier" | q:VOLATILE => "VolatileTypeQualifier" | q:RESTRICT => "RestrictTypeQualifier" /* C99 */ ; init_declr : declr:declr init:(e:'=' init:init_)? => "InitDeclr" ; designator : l:'[' idx:expr r:']' => "ArrayElemDesignator" | d:'.' field:IDSYM => "FieldDesignator" ; designation : desigs:(desig:designator)+ e:'=' => "Designation" ; inner_init : desig:(desig:designation)? init:init_ => "InnerInitializer" ; init_ : expr:assign_expr => "ExprInit" | l:'{' inits:(init:inner_init)+[','] c:(c:',')? r:'}' => "BlockInit" ; enum_ : name:IDSYM init:(e:'=' val:expr)? => "EnumerationItem" ; declr : ptr:(ptr:pointer)? direct:direct_declr => "Declarator" ; abst_declr : ptr:pointer => "PointerAbstDecl" | ptr:(ptr:pointer)? direct:direct_abst_declr => "DirectAbstDecl" ; direct_declr : name:IDSYM => "DeclarNameDirDeclr" | l:'(' ptr:(ptr:pointer)? direct:direct_declr r:')' => "ParenNameDirDeclr" /* C89: | declr:direct_declr '[' expr:(expr)? ']' => "BracketNameDirDeclr" */ /* C99 has the next two instead */ | declr:direct_declr l:'[' quals:(qual:type_qual)* expr:(expr:assign_expr)? r:']' => "BasicArrayDirDeclr" | declr:direct_declr l:'[' quals1:(qual:type_qual)* kw:STATIC quals2:(qual:type_qual)* expr:assign_expr r:']' => "StaticArrayDirDeclr" | declr:direct_declr l:'[' quals:(qual:type_qual)* s:'*' r:']' => "VariableArrayDirDeclr" | declr:direct_declr l:'(' params:param_type_list r:')' => "TypeFuncListDirDeclr" | declr:direct_declr l:'(' idents:(ident:IDSYM)*[','] r:')' => "IDFuncListDirDeclr" ; direct_abst_declr : l:'(' declr:abst_declr r:')' => "ParenAbstDecl" /* C89: | declr:(direct_abst_declr)? '[' expr:expr ']' => "ArrayAbstDecl"*/ | declr:(declr:direct_abst_declr)? l:'[' expr:(expr:assign_expr)? r:']' => "ArrayAbstDecl" | declr:(declr:direct_abst_declr)? l:'[' s:'*' r:']' => "VariableAbstDecl" | declr:direct_abst_declr l:'(' params:(params:param_type_list)? r:')' => "NestedFuncAbstDecl" | l:'(' params:(params:param_type_list)? r:')'=> "FuncAbstDecl" ; struct_decl : spec_quals:(spec_qual:type_spec_qual)+ declrs:(declr:struct_declr)+[','] semi:';' => "StructDecl" | p:PREPROC => "PreprocMember" ; struct_declr : declr:declr => "StructDeclr" | declr:(declr:declr)? c:':' expr:expr => "BitfieldDeclr" ; pointer : s:'*' quals:(qual:type_qual)* ptr:(ptr:pointer)? => "Pointer" ; param_decl : specs:(spec:decl_spec)+ declr:declr => "NamedParamDecl" | specs:(spec:decl_spec)+ declr:(declr:abst_declr)? => "UnnamedParamDecl" ; param_type_list : decls:(decl:param_decl)+[','] dotdotdot:(c:',' ddd:ELLIPSIS)? => "ParameterTypeList" ; for_init : expr:(expr:exprs)? semi:';' => "ExpressionInit" | decl:decl /* C99 */ => "DeclarationInit" ; stmt : label:IDSYM c:':' stmt:stmt => "LabeledStatement" | kw:CASE expr:expr c:':' stmt:stmt => "CaseLabelStatement" | kw:DEFAULT c:':' stmt:stmt => "DefaultLabelStatement" | expr:(expr:exprs)? semi:';' => "ExprStatement" | stmt:comp_stmt => "CompoundStatement" | kw:IF l:'(' pred:exprs r:')' t_stmt:stmt %prec BARE_IF_PREC => "IfNoElseStatement" | k1:IF l:'(' pred:exprs r:')' t_stmt:stmt k2:ELSE f_stmt:stmt => "IfElseStatement" | kw:SWITCH l:'(' val:exprs r:')' stmt:stmt => "SwitchStatement" | kw:WHILE l:'(' val:exprs r:')' stmt:stmt => "WhileStatement" | k1:DO stmt:stmt k2:WHILE l:'(' val:exprs r:')' semi:';' => "DoWhileStatement" | kw:FOR l:'(' init:for_init pred:(expr:exprs)? semi:';' inc:(expr:exprs)? r:')' stmt:stmt => "ForStatement" | kw:GOTO label:IDSYM semi:';' => "GotoStatement" | kw:CONTINUE semi:';' => "ContinueStatement" | kw:BREAK semi:';' => "BreakStatement" | kw:RETURN ret:(expr:exprs)? semi:';' => "ReturnStatement" | p:PREPROC => "PreprocStatement" ; block_item : decl:decl => "DeclarationItem" | stmt:stmt => "StatementItem" ; comp_stmt /* C89: : '{' decls:(decl:decl)* stmts:(stmt:stmt)* '}' => "BlockStatement" */ : l:'{' items:(item_:block_item)* r:'}' /* C99 */ => "BlockStatement" ; exprs : left:exprs op:',' right:assign_expr %prec COMMA_PREC => "CommaList" | expr:assign_expr => "SingleExpr" ; arg_expr: expr:assign_expr => "ExpressionArgument" | type:type_name => "FakeTypeArgument" ; assign_expr : left:expr op:'=' right:assign_expr => "NormalAssign" | left:expr op:MULASSIGN right:assign_expr => "MultiplyAssign" | left:expr op:DIVASSIGN right:assign_expr => "DivideAssign" | left:expr op:MODASSIGN right:assign_expr => "ModAssign" | left:expr op:ADDASSIGN right:assign_expr => "AddAssign" | left:expr op:SUBASSIGN right:assign_expr => "SubtractAssign" | left:expr op:SHLASSIGN right:assign_expr => "ShiftLeftAssign" | left:expr op:SHRASSIGN right:assign_expr => "ShiftRightAssign" | left:expr op:ANDASSIGN right:assign_expr => "AndAssign" | left:expr op:XORASSIGN right:assign_expr => "XorAssign" | left:expr op:ORASSIGN right:assign_expr => "OrAssign" | expr:expr => "SimpleExpression" ; expr /* Optional texpr V is a GNU extension */ : pred:expr q:'?' texpr:(expr:exprs)? c:':' fexpr:expr => "TernaryOp" | left:expr op:LOR right:expr => "LogicalOr" | left:expr op:LAND right:expr => "LogicalAnd" | left:expr op:BOR right:expr => "BitwiseOr" | left:expr op:BXOR right:expr => "BitwiseXor" | left:expr op:BAND right:expr => "BitwiseAnd" | left:expr op:EQ right:expr => "Equals" | left:expr op:NE right:expr => "NotEquals" | left:expr op:LT right:expr => "LessThan" | left:expr op:GT right:expr => "GreaterThan" | left:expr op:LE right:expr => "LessThanEquals" | left:expr op:GE right:expr => "GreaterThanEquals" | left:expr op:LSHIFT right:expr => "LeftShift" | left:expr op:RSHIFT right:expr => "RightShift" | left:expr op:'+' right:expr => "Add" | left:expr op:'-' right:expr => "Subtract" | left:expr op:'*' right:expr => "Multiply" | left:expr op:'/' right:expr => "Divide" | left:expr op:'%' right:expr => "Modulo" | l:'(' name:type_name r:')' expr:expr %prec CAST => "TypeCast" | op:'&' expr:expr %prec UNARY => "AddressOf" | op:'+' expr:expr %prec UNARY => "Positive" | op:'-' expr:expr %prec UNARY => "Negate" | op:'~' expr:expr %prec UNARY => "BitwiseNegate" | op:'!' expr:expr => "LogicalNot" | func:expr l:'(' exprs:(expr:arg_expr)*[','] r:')' %prec POSTFIX => "FunctionCall" | op:INC expr:expr %prec UNARY => "PreIncrement" | op:DEC expr:expr %prec UNARY => "PreDecrement" | expr:expr op:INC %prec POSTFIX => "PostIncrement" | expr:expr op:DEC %prec POSTFIX => "PostDecrement" | op:SIZEOF expr:expr %prec UNARY => "VarSizeof" | op:SIZEOF l:'(' type:type_name r:')' %prec UNARY => "TypeSizeof" | l:'(' expr:exprs r:')' => "ParenthExpr" | val:int_const => "IntegerConstant" | val:char_const => "CharacterConstant" | val:float_const => "FloatingConstant" | val:str_const => "StringConstant" | lp:'(' type:type_name rp:')' lb:'{' inits:(init:inner_init)+[','] c:(c:',')? rb:'}' /* C99 */ => "CompoundLiteral" | name:IDSYM => "VariableExpr" | expr:expr op:'.' field:IDSYM %prec POSTFIX => "StructAccess" | expr:expr op:PTR field:IDSYM %prec POSTFIX => "PointerAccess" | expr:expr l:'[' index:exprs r:']' %prec POSTFIX => "ArrayAccess" | op:'*' expr:expr %prec UNARY => "PointerDereference" ; int_const : it:INT_CONST => "PlainIntegerConstant" | it:INT_CONST_U => "UnsignedIntegerConstant" | it:INT_CONST_L => "LongIntegerConstant" | it:INT_CONST_UL => "UnsignedLongIntegerConstant" | it:INT_CONST_LL => "LongLongIntegerConstant" /* C99 */ | it:INT_CONST_ULL => "UnsignedLongLongIntegerConstant" /* C99 */ ; str_const : strs:(str:STR_CONST)+ => "PlainStringConstant" | strs:(str:WIDE_STR_CONST)+ => "WideStringConstant" ; char_const : it:CHAR_CONST => "PlainCharacterConstant" | it:WIDE_CHAR_CONST => "WideCharacterConstant" ; float_const : it:FLOAT_CONST => "FloatConstant" | it:DOUBLE_CONST => "DoubleConstant" | it:LONGDOUBLE_CONST => "LongDoubleConstant" ; %%