Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds Ion Schema 2.0 specification #82

Merged
merged 12 commits into from
Sep 22, 2022
Merged
5 changes: 5 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -251,13 +251,18 @@ GEM
unf_ext
unf_ext (0.0.8.2)
unicode-display_width (1.8.0)
webrick (1.7.0)
zeitwerk (2.6.0)

PLATFORMS
ruby

DEPENDENCIES
github-pages
webrick (~> 1.7)

RUBY VERSION
ruby 2.6.8p205

BUNDLED WITH
1.17.2
2 changes: 1 addition & 1 deletion _config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ baseurl: /ion-schema
markdown: kramdown
kramdown:
input: GFM
toc_levels: "2,3"
toc_levels: "1,2"
highlighter: rouge
defaults:
-
Expand Down
179 changes: 179 additions & 0 deletions _includes/grammar-2-0.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
<ISL_VERSION_MARKER> ::= $ion_schema_2_0

<SCHEMA> ::= <ISL_VERSION_MARKER> <NAMED_TYPE_DEFINITION>...
| <ISL_VERSION_MARKER> <HEADER> <NAMED_TYPE_DEFINITION>... <FOOTER>

<HEADER> ::= schema_header::{ <HEADER_FIELD>... }

<HEADER_FIELD> ::= <IMPORTS_DECLARATION>
| <USER_CONTENT_DECLARATION>

<IMPORTS_DECLARATION> ::= imports: [ <IMPORT>... ],

<IMPORT> ::= <IMPORT_SCHEMA>
| <IMPORT_TYPE>
| <IMPORT_TYPE_ALIAS>

<IMPORT_SCHEMA> ::= { id: <SCHEMA_ID> }

<IMPORT_TYPE> ::= { id: <SCHEMA_ID>, type: <TYPE_NAME> }

<IMPORT_TYPE_ALIAS> ::= { id: <SCHEMA_ID>, type: <TYPE_NAME>, as: <TYPE_NAME> }

<USER_CONTENT_DECLARATION> ::= user_content: { <USER_CONTENT_DECLARATION_FIELD>... }

<USER_CONTENT_DECLARATION_FIELD> ::= schema_header: [ <SYMBOL>... ],
| type: [ <SYMBOL>... ],
| schema_footer: [ <SYMBOL>... ],

<FOOTER> ::= schema_footer::{ }

<NAMED_TYPE_DEFINITION> ::= type::{ name: <TYPE_NAME>, <CONSTRAINT>... }

<INLINE_TYPE_DEFINITION> ::= { <CONSTRAINT>... }

<SCHEMA_ID> ::= <STRING>
| <SYMBOL>

<TYPE_NAME> ::= <SYMBOL>

<TYPE_REFERENCE> ::= <TYPE_NAME>
| $null_or::<TYPE_NAME>
| <INLINE_TYPE_DEFINITION>
| $null_or::<INLINE_TYPE_DEFINITION>
| <IMPORT_TYPE>
| $null_or::<IMPORT_TYPE>

<OCCURS> ::= occurs: <INT>
| occurs: <RANGE_INT>
| occurs: optional
| occurs: required

<VARIABLY_OCCURRING_TYPE_REFERENCE> ::= { <OCCURS>, <CONSTRAINT>... }
| <TYPE_REFERENCE>

<NUMBER> ::= <DECIMAL>
| <FLOAT>
| <INT>

<EXCLUSIVITY> ::= exclusive::
| ""

<RANGE_INT> ::= range::[ <EXCLUSIVITY><INT>, <EXCLUSIVITY><INT> ]
| range::[ min, <EXCLUSIVITY><INT> ]
| range::[ <EXCLUSIVITY><INT>, max ]

<RANGE_NUMBER> ::= range::[ <EXCLUSIVITY><NUMBER>, <EXCLUSIVITY><NUMBER> ]
| range::[ min, <EXCLUSIVITY><NUMBER> ]
| range::[ <EXCLUSIVITY><NUMBER>, max ]

<RANGE_TIMESTAMP> ::= range::[ <EXCLUSIVITY><TIMESTAMP>, <EXCLUSIVITY><TIMESTAMP> ]
| range::[ min, <EXCLUSIVITY><TIMESTAMP> ]
| range::[ <EXCLUSIVITY><TIMESTAMP>, max ]

<RANGE_TIMESTAMP_PRECISION> ::= range::[ <EXCLUSIVITY><TIMESTAMP_PRECISION_VALUE>, <EXCLUSIVITY><TIMESTAMP_PRECISION_VALUE> ]
| range::[ min, <EXCLUSIVITY><TIMESTAMP_PRECISION_VALUE> ]
| range::[ <EXCLUSIVITY><TIMESTAMP_PRECISION_VALUE>, max ]

<CONSTRAINT> ::= <ALL_OF>
| <ANNOTATIONS>
| <ANY_OF>
| <BYTE_LENGTH>
| <CODEPOINT_LENGTH>
| <CONTAINER_LENGTH>
| <CONTAINS>
| <CONTENT>
| <ELEMENT>
| <EXPONENT>
| <FIELDS>
| <FIELD_NAMES>
| <IEEE745_FLOAT>
| <NOT>
| <ONE_OF>
| <ORDERED_ELEMENTS>
| <PRECISION>
| <REGEX>
| <TIMESTAMP_OFFSET>
| <TIMESTAMP_PRECISION>
| <TYPE>
| <VALID_VALUES>

<ALL_OF> ::= all_of: [ <TYPE_REFERENCE>... ]

<ANNOTATIONS_MODIFIER> ::= required::
| closed::

<ANNOTATIONS> ::= annotations: <ANNOTATIONS_MODIFIER>... [ <SYMBOL>... ]
| annotations: <TYPE_REFERENCE>

<ANY_OF> ::= any_of: [ <TYPE_REFERENCE>... ]

<BYTE_LENGTH> ::= byte_length: <INT>
| byte_length: <RANGE_INT>

<CODEPOINT_LENGTH> ::= codepoint_length: <INT>
| codepoint_length: <RANGE_INT>

<CONTAINER_LENGTH> ::= container_length: <INT>
| container_length: <RANGE_INT>

<CONTAINS> ::= contains: [ <VALUE>... ]

<ELEMENT> ::= element: <TYPE_REFERENCE>
| element: distinct::<TYPE_REFERENCE>

<EXPONENT> ::= exponent: <INT>
| exponent: <RANGE_INT>

<FIELD> ::= <SYMBOL>: <VARIABLY_OCCURRING_TYPE_REFERENCE>

<FIELDS> ::= fields: { <FIELD>... }
| fields: closed::{ <FIELD>... }

<FIELD_NAMES> ::= field_names: <TYPE_REFERENCE>
| field_names: distinct::<TYPE_REFERENCE>

<IEEE754_FLOAT> ::= ieee754_float: binary16
| ieee754_float: binary32
| ieee754_float: binary64

<NOT> ::= not: <TYPE_REFERENCE>

<ONE_OF> ::= one_of: [ <TYPE_REFERENCE>... ]

<ORDERED_ELEMENTS> ::= ordered_elements: [ <VARIABLY_OCCURRING_TYPE_REFERENCE>... ]

<PRECISION> ::= precision: <INT>
| precision: <RANGE_INT>

<REGEX> ::= regex: <STRING>
| regex: i::<STRING>
| regex: m::<STRING>
| regex: i::m::<STRING>

<TIMESTAMP_OFFSET> ::= timestamp_offset: [ "[+|-]hh:mm"... ]

<TIMESTAMP_PRECISION_VALUE> ::= year
| month
| day
| minute
| second
| millisecond
| microsecond
| nanosecond

<TIMESTAMP_PRECISION> ::= timestamp_precision: <TIMESTAMP_PRECISION_VALUE>
| timestamp_precision: <RANGE_TIMESTAMP_PRECISION>

<TYPE> ::= type: <TYPE_REFERENCE>

<UTF8_BYTE_LENGTH> ::= utf8_byte_length: <INT>
| utf8_byte_length: <RANGE_INT>

<VALID_VALUES> ::= valid_values: [ <VALUE_OR_RANGE>... ]
| valid_values: <RANGE_NUMBER>
| valid_values: <RANGE_TIMESTAMP>

<VALUE_OR_RANGE> ::= <VALUE>
| <RANGE_NUMBER>
| <RANGE_TIMESTAMP>
26 changes: 26 additions & 0 deletions _includes/grammar-element.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<!--
Arguments:
productions: a comma separated list of production names. E.g. "TIMESTAMP_PRECISION,TIMESTAMP_PRECISION_VALUE"

TODO: When introducing ISL 2.1, make this accept an argument containing the ISL version number.
-->
{% assign productions = include.productions | upcase | split: "," %}
{% capture grammar %}
{% include grammar-2-0.txt %}
{% endcapture %}
{% assign grammar_lines = grammar | escape_once | newline_to_br | split: '<br />' %}

<div class="bs-callout bs-callout-grammar">
<pre>
{%- for production in productions -%}
{%- assign is_in_production = false -%}
{%- assign production_start = "&lt;PRODUCTION> ::=" | escape_once | replace: "PRODUCTION", production -%}
{%- for grammar_line in grammar_lines -%}
{%- assign grammar_line_stripped = grammar_line | strip -%}
{%- if grammar_line contains production_start -%}{%- assign is_in_production = true -%}{%- endif -%}
{%- if is_in_production -%}{{- grammar_line | escape_once -}}{%- endif -%}
{%- if is_in_production and grammar_line_stripped == "" -%}{%- break -%}{%- endif -%}
{%- endfor -%}
{%- endfor -%}
</pre>
</div>
2 changes: 1 addition & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ redirect_from:

* [Ion Schema Language Versioning](isl-versioning)
* [Ion Schema 1.0 Specification](isl-1-0/spec)
* Ion Schema 2.0 Specification (Coming soon!)
* [Ion Schema 2.0 Specification](isl-2-0/spec)

### Cookbooks

Expand Down
14 changes: 14 additions & 0 deletions docs/isl-2-0/bnf-grammar.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
title: Ion Schema 2.0 BNF-Style Grammar
---
# {{page.title}}

This grammar is intended as a learning aid and is _not_ authoritative.

Some limitations of this grammar are that it cannot accurately represent open content, that it excludes equivalent encodings of an Ion value (e.g. the symbol `year` could also be `'year'`), that it does not describe a valid ISL regex string, and that it does not describe reserved words that cannot be used as a type name.
For an authoritative grammar, see [`ion-schema-schemas`](https://github.com/amzn/ion-schema-schemas).
tgregg marked this conversation as resolved.
Show resolved Hide resolved

{% capture grammar %}{% include grammar-2-0.txt %}{% endcapture %}
<pre class="grammar">
{{ grammar | escape_once }}
</pre>
Loading