<p>I have created a simple markup language that consists of simple tags to write my blog contents. I write my blog posts in that language and convert them into HTML with a compiler.</p>
<p>Users can specify the document language and if the document supports multilanguage. The document can only have two languages: <em>&quot;Turkish (tr)&quot;</em> and <em>&quot;English (en)&quot;</em>. Both headers are required, but their orders are not important.</p>
<p>Examples of documents following this specification:</p>
<pre><code>#lang en
#mul yes

And other tags and content...
</code></pre>
<pre><code>#lang tr
#mul yes

And other tags and content...
</code></pre>
<pre><code>#lang en
#mul no

And other tags and content...
</code></pre>
<p>This is my current EBNF grammar for the headers:</p>
<pre><code>YesNo = &quot;yes&quot; | &quot;no&quot;
Doclanguage = &quot;#lang&quot; &quot;tr&quot; | &quot;en&quot; 
Multilingual = &quot;#mul&quot; YesNo

DocumentHeader = Doclanguage Multilingual 
</code></pre>
<p>However, I want <code>Doclanguage</code> and <code>Multilingual</code> to be valid regardless of order, i.e. this should also be valid:</p>
<pre><code>#mul yes
#lang en

And other tags and content...
</code></pre>
<p>Obviously, one can transform the grammar to the below.</p>
<pre><code>YesNo = &quot;yes&quot; | &quot;no&quot;
Doclanguage = #lang &quot;tr&quot; | &quot;en&quot; 
Multilingual = #mul YesNo

DocumentHeader = Doclanguage Multilingual | Multilingual Doclanguage
</code></pre>
<p>But what if I have more than two nonterminals in the header? Say four or more, for example. In that cade, it is also hard to write parsing function for such a grammar. <strong>Is there way of writing such a grammar more logically</strong>?</p>
<h3>Updated Grammar After Answer</h3>
<p>The accepted answer is simple and effective.</p>
<p>According to the given suggestion, the updated grammar using EBNF syntax is as follows.</p>
<pre><code>yesno = &quot;yes&quot; | &quot;no&quot;
Doclanguage = &quot;#lang&quot; &quot;tr&quot; | &quot;en&quot;
Multilingual = &quot;#mul&quot; yesno  

ObligatoryHeaderItem = Doclanguage | Multilingual
ObligatoryHeader = ObligatoryHeaderItem { ObligatoryHeaderItem }
<span class="math-container">```</span> 
</code></pre>

<grammar>
Order-independency of Nonterminals in EBNF Grammar Spec
<p>I would define a non-terminal for a document header items, then define a document header as a sequence of them:</p>
<pre><code>DocumentHeaderItem = Doclanguage | Multilingual 
DocumentHeader = DocumentHeaderItem*
</code></pre>
<p>You may also want to specify that a document has exactly one of each header item, or at least one of each; but it is easier to enforce such rules after parsing, rather than encode those rules in your grammar. There may be some incorrect combinations, but they don't have to be syntax errors, they can be semantic errors instead.</p>
<p>This approach also makes it easier to add more kinds of header item later, and easier to change the rules for which header items are allowed or required in what quantities.</p>

CC BY-SA 4.0
2023-07-03T15:55:08.690Z
2023-07-03T16:17:46.537Z
2023-07-03T16:17:46.537Z
kaya3
CC BY-SA 4.0
2023-07-03T16:15:29.630Z
No, I don't want the document to have exactly one of each header item. It can have more than one of the same header element. Anyway yes, your method seems reasonable and it is the closest answer to my question.
jtxkopt - Stand With Palestine
<h2>Extend EBNF further</h2>
<p>EBNF has two ways that it can be extended further.</p>
<p>The first is that any text in <code>? ... ?</code> is totally unspecified in how it's parsed. This is frequently used for things where it's easier to describe the contents rather than enumerate them:</p>
<pre><code>whitespace = ? white space characters ? ;
</code></pre>
<p>The second is that an identifier followed immediately by a paren isn't allowed. From <a href="https://en.wikipedia.org/wiki/Extended_Backus%E2%80%93Naur_form#Extensibility" rel="nofollow noreferrer">the Wikipedia article on EBNF</a>:</p>
<blockquote>
<p>The following is <em>not</em> valid EBNF:</p>
<pre><code>something = foo ( bar );
</code></pre>
<p>Therefore, an extension of EBNF could use that notation. For example, in a Lisp grammar, function application could be defined by the following rule:</p>
<pre><code>function application = list( symbol, { expression } );
</code></pre>
</blockquote>
<p>So, you could define a function such as <code>set</code> which requires all of its arguments but in any order, and say</p>
<pre><code>DocumentHeader = set( Doclanguage, Multilingual );
</code></pre>

CC BY-SA 4.0
2023-07-03T15:53:56.823Z
2023-07-03T15:53:56.823Z
Bbrk24
<p>If you don't need to require that all of the header types are included for every blog post, you could do:</p>
<pre><code>YesNo = &quot;yes&quot; | &quot;no&quot;
Doclanguage = #lang &quot;tr&quot; | &quot;en&quot; 
Multilingual = #mul YesNo
OneHeader = Multilingual | DocLanguage | ...
DocumentHeader = OneHeader DocumentHeader | OneHeader
</code></pre>

CC BY-SA 4.0
2023-07-03T15:52:40.663Z
2023-07-03T15:52:40.663Z
pppery
CC BY-SA 4.0
2023-07-03T16:07:33.867Z
The header elements are obligatory. (I edited the question.)
jtxkopt - Stand With Palestine
# Order-independency of Nonterminals in EBNF Grammar Spec
Posted by: username_0 on 2023-07-03
I have created a simple markup language that consists of simple tags to write my blog contents. I write my blog posts in that language and convert them into HTML with a compiler.
Users can specify the document language and if the document supports multilanguage. The document can only have two languages: "Turkish (tr)" and "English (en)". Both headers are required, but their orders are not important.
Examples of documents following this specification:
#lang en
#mul yes

And other tags and content...

#lang tr
#mul yes

And other tags and content...

#lang en
#mul no

And other tags and content...

This is my current EBNF grammar for the headers:
YesNo = "yes" | "no"
Doclanguage = "#lang" "tr" | "en" 
Multilingual = "#mul" YesNo

DocumentHeader = Doclanguage Multilingual 

However, I want Doclanguage and Multilingual to be valid regardless of order, i.e. this should also be valid:
#mul yes
#lang en

And other tags and content...

Obviously, one can transform the grammar to the below.
YesNo = "yes" | "no"
Doclanguage = #lang "tr" | "en" 
Multilingual = #mul YesNo

DocumentHeader = Doclanguage Multilingual | Multilingual Doclanguage

But what if I have more than two nonterminals in the header? Say four or more, for example. In that cade, it is also hard to write parsing function for such a grammar. Is there way of writing such a grammar more logically?
Updated Grammar After Answer
The accepted answer is simple and effective.
According to the given suggestion, the updated grammar using EBNF syntax is as follows.
yesno = "yes" | "no"
Doclanguage = "#lang" "tr" | "en"
Multilingual = "#mul" yesno  

ObligatoryHeaderItem = Doclanguage | Multilingual
ObligatoryHeader = ObligatoryHeaderItem { ObligatoryHeaderItem }
```
**Tags:** grammar
---
## 3 answers
### Answer by username_1 on 2023-07-03. Score: 5 | Accepted answer
I would define a non-terminal for a document header items, then define a document header as a sequence of them:
DocumentHeaderItem = Doclanguage | Multilingual 
DocumentHeader = DocumentHeaderItem*

You may also want to specify that a document has exactly one of each header item, or at least one of each; but it is easier to enforce such rules after parsing, rather than encode those rules in your grammar. There may be some incorrect combinations, but they don't have to be syntax errors, they can be semantic errors instead.
This approach also makes it easier to add more kinds of header item later, and easier to change the rules for which header items are allowed or required in what quantities.
> **Comments:**
> **username_0** (2023-07-03): No, I don't want the document to have exactly one of each header item. It can have more than one of the same header element. Anyway yes, your method seems reasonable and it is the closest answer to my question.  
---
### Answer by username_2 on 2023-07-03. Score: 2
Extend EBNF further
EBNF has two ways that it can be extended further.
The first is that any text in ? ... ? is totally unspecified in how it's parsed. This is frequently used for things where it's easier to describe the contents rather than enumerate them:
whitespace = ? white space characters ? ;

The second is that an identifier followed immediately by a paren isn't allowed. From the Wikipedia article on EBNF:

The following is not valid EBNF:
something = foo ( bar );

Therefore, an extension of EBNF could use that notation. For example, in a Lisp grammar, function application could be defined by the following rule:
function application = list( symbol, { expression } );


So, you could define a function such as set which requires all of its arguments but in any order, and say
DocumentHeader = set( Doclanguage, Multilingual );
---
### Answer by username_3 on 2023-07-03. Score: 2
If you don't need to require that all of the header types are included for every blog post, you could do:
YesNo = "yes" | "no"
Doclanguage = #lang "tr" | "en" 
Multilingual = #mul YesNo
OneHeader = Multilingual | DocLanguage | ...
DocumentHeader = OneHeader DocumentHeader | OneHeader
> **Comments:**
> **username_0** (2023-07-03): The header elements are obligatory. (I edited the question.)  
---
