grammar XdrDeclarationGrammar

rule declaration
  void_decl /
  opaque_decl /
  string_decl /
  array_decl /
  optional_decl /
  simple_decl
end

rule void_decl
  "void" 
  <Xdrgen::AST::Declarations::Void>
end

rule opaque_decl
  type_s:("opaque" <Xdrgen::AST::Typespecs::Opaque>)
  space 
  identifier 
  size_spec:(fixed_size_spec / var_size_spec)
  <Xdrgen::AST::Declarations::Opaque>
end

rule string_decl
  type_s:("string" <Xdrgen::AST::Typespecs::String>)
  space 
  identifier 
  size_spec:var_size_spec 
  <Xdrgen::AST::Declarations::String>
end

rule array_decl
  type_s:type_specifier
  space
  identifier
  size_spec:(fixed_size_spec / var_size_spec)
  <Xdrgen::AST::Declarations::Array>
end

rule optional_decl
  type_s:type_specifier 
  ("*" space? / space? "*")
  identifier 
  <Xdrgen::AST::Declarations::Optional>
end

rule simple_decl
  type_s:type_specifier 
  space 
  identifier
  <Xdrgen::AST::Declarations::Simple>
end

rule type_specifier
  (integral_type_spec /
  float_type_spec /
  boolean_type_spec /
  enum_type_spec /
  struct_type_spec /
  union_type_spec /
  (identifier <Xdrgen::AST::Typespecs::Simple>))
end

rule integral_type_spec
  (("int" <Xdrgen::AST::Typespecs::Int>) /
  ("hyper" <Xdrgen::AST::Typespecs::Hyper>) /
  ("unsigned int" <Xdrgen::AST::Typespecs::UnsignedInt>)/
  ("unsigned hyper" <Xdrgen::AST::Typespecs::UnsignedHyper>))
  type_suffix
end

rule float_type_spec
  (("float" <Xdrgen::AST::Typespecs::Float>) / 
  ("double" <Xdrgen::AST::Typespecs::Double>) / 
  ("quadruple" <Xdrgen::AST::Typespecs::Quadruple>) )
  type_suffix
end

rule boolean_type_spec
  "bool"
  type_suffix
  <Xdrgen::AST::Typespecs::Bool>
end

rule type_suffix
  &(space / "*")
end

rule fixed_size_spec
  "[" size_t:size "]"
  <Xdrgen::AST::FixedSize>
end

rule var_size_spec
  "<" size_t:size? ">"
  <Xdrgen::AST::VarSize>
end

end