module WebIDL module Parser # http://dev.w3.org/2006/webapi/WebIDL/#idl-grammar grammar IDL rule Definitions ws metadef:(eal:ExtendedAttributeList ws d:Definition ws defs:Definitions)? ws end rule Definition Module / Interface / Exception / TypeDef / ImplementsStatement end rule Module "module" ws name:identifier ws "{" ws defs:Definitions ws "}" ws ";" end rule Interface "interface" ws name:identifier ws inherits:InterfaceInheritance ws "{" ws members:InterfaceMembers ws "}" ws ";" end rule InterfaceInheritance (":" ws names:ScopedNameList )? end # extract to a generic Members syntax node? rule InterfaceMembers (eal:ExtendedAttributeList ws member:InterfaceMember ws members:InterfaceMembers ws )? end rule InterfaceMember Const / AttributeOrOperation end rule Exception "exception" ws name:identifier ws "{" ws members:ExceptionMembers ws "}" ws ";" end # extract to a generic Members syntax node? rule ExceptionMembers (eal:ExtendedAttributeList ws member:ExceptionMember ws members:ExceptionMembers ws )? end rule TypeDef "typedef" ws type:Type ws name:identifier ws ";" end rule ImplementsStatement implementor:ScopedName ws "implements" ws implementee:ScopedName ws ";" end rule Const "const" ws type:Type ws name:identifier ws "=" ws const_expr:ConstExpr ws ";" end rule ConstExpr BooleanLiteral / integer / float end rule BooleanLiteral ("true" / "false") { def build() text_value == "true" end } end rule AttributeOrOperation StringifierAttributeOrOperation / Attribute / Operation end rule StringifierAttributeOrOperation "stringifier" ws a_or_op:(Attribute / OperationRest / ";") end rule Attribute readonly:ReadOnly ws "attribute" ws type:Type ws name:identifier ws getraises:GetRaises ws setraises:SetRaises ws ";" end rule ReadOnly "readonly"? end rule GetRaises ("getraises" ws list:ExceptionList)? end rule SetRaises ("setraises" ws list:ExceptionList)? end rule Operation specials:(OmittableSpecials / Specials) ws op:OperationRest end rule OmittableSpecials omit:"omittable" ws Specials end rule Specials (first:Special ws rest:Specials )? end rule Special "getter" / "setter" / "creator" / "deleter" / "caller" end rule OperationRest type:ReturnType ws optional_id:OptionalIdentifier ws "(" ws args:ArgumentList ws ")" ws raises:Raises ws ";" end rule OptionalIdentifier identifier? end rule Raises ("raises" ExceptionList)? end rule ExceptionList "(" ScopedNameList ")" end rule ArgumentList (arg:Argument ws args:Arguments )? end rule Arguments ("," ws arg:Argument ws args:Arguments )? end rule Argument eal:ExtendedAttributeList ws In ws optional:Optional ws type:Type ws variadic:Ellipsis ws id:identifier end rule In "in"? end rule Optional "optional"? end rule Ellipsis "..."? end rule ExceptionMember Const / ExceptionField end rule ExceptionField type:Type ws id:identifier ws ";" end rule ExtendedAttributeList ("[" ws attribute:ExtendedAttribute ws attributes:ExtendedAttributes ws "]" )? end rule ExtendedAttributes ("," ws attribute:ExtendedAttribute ws attributes:ExtendedAttributes )? end # # avoid infinite recursion trouble with the actual spec by using the "more restricted" ones # rule ExtendedAttribute ExtendedAttributeNamedArgList / ExtendedAttributeIdent / ExtendedAttributeScopedName / ExtendedAttributeArgList / ExtendedAttributeNoArg end rule ExtendedAttributeNoArg identifier { def build(parent) Ast::ExtendedAttribute.new(text_value) end } end rule ExtendedAttributeArgList name:identifier "(" ws args:ArgumentList ws ")" end rule ExtendedAttributeScopedName key:identifier "=" scoped_name:ScopedName end rule ExtendedAttributeIdent key:identifier "=" value:identifier !"::" end rule ExtendedAttributeNamedArgList key:identifier "=" value:(name:identifier "(" ws args:ArgumentList ws ")" ) end # rule ExtendedAttribute # "(" ws ExtendedAttributeInner ws ")" ws ExtendedAttributeRest # / "[" ws ExtendedAttributeInner ws "]" ws ExtendedAttributeRest # / "{" ws ExtendedAttributeInner ws "}" ws ExtendedAttributeRest # / Other ws ExtendedAttributeRest # end # # rule ExtendedAttributeRest # ExtendedAttribute? # end # # rule ExtendedAttributeInner # ( "(" ws ExtendedAttributeInner ws ")" ws ExtendedAttributeInner # / "[" ws ExtendedAttributeInner ws "]" ws ExtendedAttributeInner # / "{" ws ExtendedAttributeInner ws "}" ws ExtendedAttributeInner # / OtherOrComma ExtendedAttributeInner)? # end # rule Other integer / float / identifier / string / other / "..." / ":" / "::" / ";" / "<" / "=" / ">" / "?" / "false" / "object" / "true" / "any" / "attribute" / "boolean" / "caller" / "const" / "creator" / "deleter" / "double" / "exception" / "float" / "getraises" / "getter" / "implements" / "in" / "interface" / "long" / "module" / "octet" / "omittable" / "optional" / "raises" / "sequence" / "setraises" / "setter" / "short" / "DOMString" / "stringifier" / "typedef" / "unsigned" / "void" end rule OtherOrComma Other / "," end rule Type type:( NullableType / ScopedName / "any" # not sure why these two are here, since / "object" # they will be caught by ScopedName anyway.. ) array:Array end # # added: cannot be followed by a NonSpace character, since e.g. DOMStringMap would break parsing # rule NullableType type:UnsignedIntegerType null:Nullable / type:"boolean" null:Nullable !NonSpace / type:"octet" null:Nullable !NonSpace / type:"float" null:Nullable !NonSpace / type:"double" null:Nullable !NonSpace / type:"DOMString" null:Nullable !NonSpace / type:"sequence" ws "<" ws Type ws ">" null:Nullable !NonSpace end rule UnsignedIntegerType "unsigned" ws IntegerType / IntegerType end rule IntegerType ("short" / "long" ws OptionalLong) end rule OptionalLong "long"? end rule Nullable "?"? end rule Array ("[" ws "]")? end rule NonSpace (!' ' .) end rule ReturnType Type / "void" end rule ScopedNameList name:ScopedName ws names:ScopedNames end rule ScopedNames ("," ScopedName ws ScopedNames)? end rule ScopedName AbsoluteScopedName / RelativeScopedName end rule AbsoluteScopedName "::" name:identifier parts:ScopedNameParts end rule RelativeScopedName name:identifier parts:ScopedNameParts end rule ScopedNameParts ("::" ws name:identifier parts:ScopedNameParts)? end rule integer (hexint / octint / decint) { def build() Integer(text_value) end} # TODO: check edge cases end rule hexint "-"? "0" [Xx] [0-9A-Fa-f]+ end rule octint "-"? "0" [0-7]+ end rule decint "-"? [0-9]* end rule float ("-"? ([0-9]+ "." [0-9]* / [0-9]* "." [0-9]+) ([Ee] [+-]? [0-9]+)? / [0-9]+ [Ee] [+-]? [0-9]+) { def build() Float(text_value) end} # TODO: check edge cases end rule identifier [A-Z_a-z] [0-9A-Z_a-z]* { def build() text_value[/^_?(.+)/, 1] end } end rule string "\"" [^"]* "\"" end rule ws ([\t\n\r ]* ((line_comment / block_comment) [\t\n\r ]*)+ / [\t\n\r ]+)? end rule other [^\t\n\r 0-9A-Z_a-z] end rule line_comment "//" (![\n\r] . )* end rule block_comment '/*' (!'*/' . )* '*/' end end # IDL end # Parser end # WebIDL