grammar DIDGrammar

rule body
  ( type_declaration / service_declaration / comment / end_of_line )* <IcAgent::Ast::Nodes::DIDFile>
end

rule base_type
  'bool' / 'text' / 'null' / 'reserved' / 'empty' / 'principal' / 'nat8' / 'nat16' / 'nat32' / 'nat64' / 'int8' / 'int16' / 'int32' / 'int64' / 'float32' / 'float64' /
  'opt' / 'vec' / 'record' / 'variant' / 'service' / 'func' / 'nat' / 'int' / blob
end

rule base_type_single
  'bool' / 'text' / 'null' / 'reserved' / 'empty' / 'principal' / 'nat8' / 'nat16' / 'nat32' / 'nat64' / 'int8' / 'int16' / 'int32' / 'int64' / 'float32' / 'float64' / 'nat' / 'int' / 'blob'
end

rule base_type_base
  base_type_single+ <IcAgent::Ast::Nodes::BaseTypeSingle>
end

rule base_type_code
  [a-zA-Z0-9_]+ <IcAgent::Ast::Nodes::BaseTypeOther>
end

rule base_type_key
    [a-zA-Z0-9_]+ <IcAgent::Ast::Nodes::BaseTypeKey>
end

rule base_type_vec
  'vec' space ic_all_type <IcAgent::Ast::Nodes::BaseTypeVec>
end

rule base_type_opt
  'opt' space ic_all_type <IcAgent::Ast::Nodes::BaseTypeOpt>
end

rule base_type_record
  'record' space '{' space_and_line ic_base_content space_and_line '}' <IcAgent::Ast::Nodes::BaseTypeRecord>
end

rule base_type_record_null
  'record {}' <IcAgent::Ast::Nodes::BaseTypeRecord>
end

rule base_type_variant
  'variant' space '{' space_and_line ic_base_content space_and_line '}' <IcAgent::Ast::Nodes::BaseTypeVariant>
end

rule base_type_func
  'func' space? "(" service_method_params? ")" space? "->" space? "(" service_method_return_type ")" space? method_query? <IcAgent::Ast::Nodes::BaseTypeFunc>
end

rule ic_all_type
  base_type_base / base_type_vec / base_type_record / base_type_record_null / base_type_variant / base_type_opt / base_type_func / base_type_code
end

rule ic_base_content
  (ic_base_type)+  <IcAgent::Ast::Nodes::BaseTypeContent>
end

rule ic_base_type
  space? base_type_key space? (':' space ic_all_type)* optional_semicolon <IcAgent::Ast::Nodes::BaseTypeChild>
end

rule type_declaration
  'type' space_and_line type_name space_and_line '=' space_and_line ic_all_type ';' end_of_line <IcAgent::Ast::Nodes::TypeDeclaration>
end

rule type_name
  [a-zA-Z0-9_]+ <IcAgent::Ast::Nodes::TypeName>
end

rule comment
  space? '//' space? rest_of_line <IcAgent::Ast::Nodes::Comment>
end

rule service_declaration
  "service" space ":" space service_name* "{" end_of_line service_methods "}"  <IcAgent::Ast::Nodes::Service>
end

rule service_name
  "(" ic_service_name ")" space? "->" space?
end

rule ic_service_name
  [a-zA-Z0-9_]* <IcAgent::Ast::Nodes::IcServiceName>
end

rule service_methods
  (service_item)+ <IcAgent::Ast::Nodes::IcServiceMethods>
end

rule service_item
  space? service_method_name space? ":" space? "(" service_method_params? ")" space? "->" space? "(" service_method_return_type ")" space? method_query? ';' end_of_line? <IcAgent::Ast::Nodes::IcServiceItem>
end

rule service_method_params
  param_element (", " param_element)* <IcAgent::Ast::Nodes::IcServiceMethodParams>
end

rule service_method_return_type
  [a-zA-Z0-9_{}: ]* <IcAgent::Ast::Nodes::IcServiceMethodReturn>
end

rule method_query
  [a-zA-Z0-9_]* <IcAgent::Ast::Nodes::IcServiceMethodQuery>
end

rule words
  [a-zA-Z_] [a-zA-Z0-9_]*
end

rule param_element
  [a-zA-Z0-9_ ]+
end

rule service_method_name
  [a-zA-Z0-9_]* <IcAgent::Ast::Nodes::IcServiceMethodName>
end

rule string_without_spaces
  [\S]* <IcAgent::Ast::Nodes::StringLiteral>
end

rule rest_of_line
  [^\n]* <IcAgent::Ast::Nodes::StringLiteral>
end

rule end_of_line
  [\n]+
end

rule block_record
  '{}'
end

rule has_end_of_line
  [\n]*
end

rule splite_code
  ' : '
end

rule space_and_line
  [\s\n]*
end

rule space
  [\s]+
end

rule start_space
  [^\s]+
end

rule optional_semicolon
  [;]*
end

end