<p>In Universities, students spend a lot of time correcting syntax errors.</p>
<p>For purposes of a thought experiment, suppose that a new language was developed that supported multiple syntaxi.</p>
<p>For a simple example, suppose that both <code>elif</code> and <code>else if</code> were permissible syntax for the same type of clause inside of an if-else block.</p>

<div class="s-table-container"><table class="s-table">
<thead>
<tr>
<th><a href="https://en.wikipedia.org/wiki/Python_(programming_language)" rel="nofollow noreferrer">Python</a></th>
<th>New Language</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>for k in range(0, 10):</code><br><br><code>    if (k // 3) == 0:</code><br><br><code>        # 'msg' is an abbreviation of...</code><br><br><code>        # .... the English word 'message'</code><br><br><code>        msg = &quot;{0} is divisible by three&quot;.format(k)</code><br><br><code>    elif: (k // 3) == 1:</code><br><br><code>        msg = &quot;{0} has remainder one when divided by three&quot;</code>    <br><br><code>    else: # (k // 3) == 2:</code>  <br><br> <code>        msg = &quot;{0} has remainder two when divided by three&quot;</code>    <br><br>    <code>    msg = msg.format(k)</code> <br><br> <code>    print(msg)</code><br><br></td>
<td><code>for k in range(0, 10):</code><br><br><code>    if (k // 3) == 0:</code><br><br><code>        # 'msg' is an abbreviation of...</code>  <br><br> <code>        # .... the English word 'message'</code>  <br><br>  <code>        msg = &quot;{0} is divisible by three&quot;</code>    <br><br>  <code>    else if: (k // 3) == 1:</code><br><br><code>        msg = &quot;{0} has remainder one when divided by three&quot;</code><br><br><code>    else: # (k // 3) == 2:</code>  <br><br><code>        msg = &quot;{0} has remainder two when divided by three&quot;</code>   <br><br>    <code>    msg = msg.format(k)</code>  <br><br> <code>    print(msg)</code></td>
</tr>
</tbody>
</table></div>

<p>As an analogy, the two strings of text <code>permissible</code> and <code>permittable</code> are equivalent in meaning, but different in syntax.</p>
<p>Likewise, <code>syntaxes</code> are <code>syntaxi</code></p>
<p>Suppose that you were tasked with writing code for a compiler such that the compiler was required to accept multiple syntaxi for <code>elif</code> clauses.</p>
<hr />
<p>What is is a standard approach in compiler design for a many-to-one mapping that accepts strings of Unicode encoded text as input and outputs the same output string for two or more different input strings?</p>
<hr />
<p>As a second example, suppose that you wanted the string of characters <code>:\n</code> to almost map to the same thing as new-line character <code>\n</code> without the colon character. Both syntaxes would be allowed</p>

<language-design><compilers><language-ergonomics><design-patterns>
Handling two different ways to write `else if`?
CC BY-SA 4.0
2024-10-12T20:55:48.067Z
I don’t really understand this question. Supporting several alternate syntaxes is hardly uncommon in programming languages, but it is not exactly a complicated affair: the parser is simply written to accept multiple syntaxes, and they are eventually normalized to some common intermediate representation. Are you asking a more specific question?
Alexis King
CC BY-SA 4.0
2024-10-12T21:00:07.730Z
Practically every parser for every programming language is a many-to-one mapping of the sort you describe, in the sense that the AST contains less information than the raw source code (omitting whitespace, comments and possibly some other details).
kaya3
CC BY-SA 4.0
2024-10-12T21:17:56.620Z
For a more concrete example, in Java it's legal to declare a variable as `int[] arr;` or `int arr[];`, both of these mean the same thing, and there would be no way to tell them apart at runtime. A compiler can be seen as a function which converts source code to meaning (at least, object code in some target language which preserves the meaning of the source code), and generally making this function many-to-one doesn't require doing anything out of the ordinary. It would take substantial care to design a compiler (or rather, a language) which *didn't* have this property.
kaya3
CC BY-SA 4.0
2024-10-12T23:13:08.123Z
Ultimately, even `1 + 1` and `2` are generally synonyms of each other. (Also, in the Python example, you made 2 mistakes: Python has `elif` rather than `elif:` before alternative conditions, and the modulo operator is `%` rather than `//` (which is integer division)
Jasmijn
CC BY-SA 4.0
2024-10-13T07:01:33.440Z
The standard approach is to write a parser where two different parses might generate the same abstract syntax tree. That's what makes the syntax tree *abstract*: because it captures meaning. If two different programs always generate two different parse trees then you probably have a *concrete* syntax tree.
Eric Lippert
CC BY-SA 4.0
2024-10-13T07:24:13.007Z
Note that the two code "blocks" are barely readable on limited width displays. Please try and use actual code blocks or (well, likely you should do that anyway) use a smaller example; There isn’t any need for such an extensive code sample just to show two words of difference (which isn’t helped by there being other differences as well).
MisterMiyagi
CC BY-SA 4.0
2024-10-13T07:28:36.183Z
Anyways, Python (and many other languages) already has examples of two syntaxes meaning the same thing. For example, `"Hello"` and `'Hello'` describe the exact same value; likewise various ways to write numbers.
MisterMiyagi
CC BY-SA 4.0
2024-10-14T20:52:48.237Z
you don't have to imagine a language like this: PHP has `elseif` but allows `else if`
Barmar
<blockquote>
<p>What is is a standard approach in compiler design for a many-to-one mapping that accepts strings of Unicode encoded text as input and outputs the same output string for two or more different input strings?</p>
</blockquote>
<p>As already mentioned in the comments by AlexisKing and kaya3, compilers already do this. Either the lexer does this conversion, mapping multiple different strings to the same token, or the parser, producing the same abstract syntax tree (AST) for a different sequence of tokens.</p>
<p>Other examples of alternate ways to write the same thing have been mentioned in the comments. I can add that in C++, you can substitute <code>and</code>, <code>or</code> and <code>not</code> for <code>&amp;&amp;</code>, <code>||</code> and <code>!</code>, among other things. Here, the differences are handled by the lexer, which will output the same token for both alternatives of each logical operator.</p>
<p>In the case of <code>else if</code> and <code>elif</code>, note that <code>else</code> and <code>if</code> can appear separately, so typically the tokenizer would generate different tokens for <code>else</code>, <code>if</code> and <code>elif</code>, and it is then up to the parser to treat the two-token sequence <code>else</code>, <code>if</code> the same as the single token <code>elif</code>.</p>
<p>There are many ways to write different things that actually mean the same thing. Consider the following two lines of code in C:</p>
<pre><code>x ^= x;
x = 0;
</code></pre>
<p>They both do the same thing (assuming <code>x</code> is an integer). The lexer and parser will treat them completely different though, it's only at a much later stage that the compiler will notice that the first line will also cause <code>x</code> to be set to zero, and will generate the same assembly for both lines.</p>

CC BY-SA 4.0
2024-10-13T09:57:06.747Z
2024-10-13T09:57:06.747Z
G. Sliepen
CC BY-SA 4.0
2024-10-15T08:35:01.253Z
..."may generate the same assembly", if the optimizer is smart enough.
Polluks
CC BY-SA 4.0
2024-10-16T08:18:00.960Z
@Polluks the default codegen in x86 asm for `= 0` is `xor reg reg`
Caleth
CC BY-SA 4.0
2024-10-17T07:23:48.247Z
@Caleth vbcc didn't, I made a report.
Polluks
# Handling two different ways to write `else if`?
Posted by: username_0 on 2024-10-12
In Universities, students spend a lot of time correcting syntax errors.

For purposes of a thought experiment, suppose that a new language was developed that supported multiple syntaxi.

For a simple example, suppose that both `elif` and `else if` were permissible syntax for the same type of clause inside of an if-else block.

| [Python](https://en.wikipedia.org/wiki/Python_(programming_language)) | New Language |
| --- | --- |
| `for k in range(0, 10):`   `if (k // 3) == 0:`   `# 'msg' is an abbreviation of...`   `# .... the English word 'message'`   `msg = "{0} is divisible by three".format(k)`   `elif: (k // 3) == 1:`   `msg = "{0} has remainder one when divided by three"`    `else: # (k // 3) == 2:`     `msg = "{0} has remainder two when divided by three"`     `msg = msg.format(k)`     `print(msg)` | `for k in range(0, 10):`   `if (k // 3) == 0:`   `# 'msg' is an abbreviation of...`     `# .... the English word 'message'`     `msg = "{0} is divisible by three"`     `else if: (k // 3) == 1:`   `msg = "{0} has remainder one when divided by three"`   `else: # (k // 3) == 2:`    `msg = "{0} has remainder two when divided by three"`     `msg = msg.format(k)`     `print(msg)` |

As an analogy, the two strings of text `permissible` and `permittable` are equivalent in meaning, but different in syntax.

Likewise, `syntaxes` are `syntaxi`

Suppose that you were tasked with writing code for a compiler such that the compiler was required to accept multiple syntaxi for `elif` clauses.

---

What is is a standard approach in compiler design for a many-to-one mapping that accepts strings of Unicode encoded text as input and outputs the same output string for two or more different input strings?

---

As a second example, suppose that you wanted the string of characters `:\n` to almost map to the same thing as new-line character `\n` without the colon character. Both syntaxes would be allowed
**Tags:** language-design compilers language-ergonomics design-patterns
> **Comments:**
> **username_1**: I don’t really understand this question. Supporting several alternate syntaxes is hardly uncommon in programming languages, but it is not exactly a complicated affair: the parser is simply written to accept multiple syntaxes, and they are eventually normalized to some common intermediate representation. Are you asking a more specific question?  
> **username_2**: Practically every parser for every programming language is a many-to-one mapping of the sort you describe, in the sense that the AST contains less information than the raw source code (omitting whitespace, comments and possibly some other details).  
> **username_2**: For a more concrete example, in Java it's legal to declare a variable as `int[] arr;` or `int arr[];`, both of these mean the same thing, and there would be no way to tell them apart at runtime. A compiler can be seen as a function which converts source code to meaning (at least, object code in some target language which preserves the meaning of the source code), and generally making this function many-to-one doesn't require doing anything out of the ordinary. It would take substantial care to design a compiler (or rather, a language) which *didn't* have this property.  
> **username_3**: Ultimately, even `1 + 1` and `2` are generally synonyms of each other. (Also, in the Python example, you made 2 mistakes: Python has `elif` rather than `elif:` before alternative conditions, and the modulo operator is `%` rather than `//` (which is integer division)  
> **username_4**: The standard approach is to write a parser where two different parses might generate the same abstract syntax tree. That's what makes the syntax tree *abstract*: because it captures meaning. If two different programs always generate two different parse trees then you probably have a *concrete* syntax tree.  
> **username_5**: Note that the two code "blocks" are barely readable on limited width displays. Please try and use actual code blocks or (well, likely you should do that anyway) use a smaller example; There isn’t any need for such an extensive code sample just to show two words of difference (which isn’t helped by there being other differences as well).  
> **username_5**: Anyways, Python (and many other languages) already has examples of two syntaxes meaning the same thing. For example, `"Hello"` and `'Hello'` describe the exact same value; likewise various ways to write numbers.  
> **username_6**: you don't have to imagine a language like this: PHP has `elseif` but allows `else if`  
---
## 1 answers
### Answer by username_7 on 2024-10-13. Score: 1
What is is a standard approach in compiler design for a many-to-one mapping that accepts strings of Unicode encoded text as input and outputs the same output string for two or more different input strings?

As already mentioned in the comments by AlexisKing and kaya3, compilers already do this. Either the lexer does this conversion, mapping multiple different strings to the same token, or the parser, producing the same abstract syntax tree (AST) for a different sequence of tokens.
Other examples of alternate ways to write the same thing have been mentioned in the comments. I can add that in C++, you can substitute and, or and not for &&, || and !, among other things. Here, the differences are handled by the lexer, which will output the same token for both alternatives of each logical operator.
In the case of else if and elif, note that else and if can appear separately, so typically the tokenizer would generate different tokens for else, if and elif, and it is then up to the parser to treat the two-token sequence else, if the same as the single token elif.
There are many ways to write different things that actually mean the same thing. Consider the following two lines of code in C:
x ^= x;
x = 0;

They both do the same thing (assuming x is an integer). The lexer and parser will treat them completely different though, it's only at a much later stage that the compiler will notice that the first line will also cause x to be set to zero, and will generate the same assembly for both lines.
> **Comments:**
> **username_8** (2024-10-15): ..."may generate the same assembly", if the optimizer is smart enough.  
> **username_9** (2024-10-16): @Polluks the default codegen in x86 asm for `= 0` is `xor reg reg`  
> **username_8** (2024-10-17): @Caleth vbcc didn't, I made a report.  
---
