grammar SpdxGrammar

rule license_expression
  compound_expression / none / no_assertion
end

rule compound_expression
  or_expression / and_expression / expression / grouped_expression
end

rule and_expression
  ( expression space <Operand> / grouped_expression space? <Operand> ) "AND" ( space ( and_expression / expression ) <Operand> / space? grouped_expression <Operand> ) <LogicalAnd>
end

rule or_expression
  ( ( and_expression / expression ) space <Operand> / grouped_expression space? <Operand> ) "OR"  ( space compound_expression <Operand> / space? grouped_expression <Operand> ) <LogicalOr>
end

rule expression
  simple_expression space "WITH" space license_exception_id <With> /
  simple_expression
end

rule grouped_expression
  '(' compound_expression ')' <GroupedExpression>
end

rule simple_expression
  license_id '+' <LicensePlus> / license_id / ref
end

rule ref
  document_ref / license_ref
end

rule license_ref
  "LicenseRef-" idstring <LicenseRef>
end

rule document_ref
  "DocumentRef-" idstring ':' license_ref <DocumentRef>
end

rule license_id
  idstring &{|seq| Spdx.license_exists?(seq.first.text_value) } <License>
end

rule license_exception_id
  idstring &{|seq| Spdx.exception_exists?(seq.first.text_value) } <LicenseException>
end

rule idstring
  [a-zA-Z0-9\-\.]+
end

rule none
  "NONE" <None>
end

rule no_assertion
  "NOASSERTION" <NoAssertion>
end

rule space
  [\s]+
end

end