<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ linguistics - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ linguistics - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sat, 27 Jun 2026 09:08:12 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/linguistics/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ What are Context Free Grammars? ]]>
                </title>
                <description>
                    <![CDATA[ By Aditya Have you ever noticed that, when you are writing code in a text editor like VS code, it recognizes things like unmatched braces? And it also sometimes warns you, with an irritating red highlight, about the incorrect syntax that you have wri... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/context-free-grammar/</link>
                <guid isPermaLink="false">66d45dd951f567b42d9f843b</guid>
                
                    <category>
                        <![CDATA[ compilers ]]>
                    </category>
                
                    <category>
                        <![CDATA[ finite state machine ]]>
                    </category>
                
                    <category>
                        <![CDATA[ linguistics ]]>
                    </category>
                
                    <category>
                        <![CDATA[ programming languages ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 14 Jan 2020 09:39:14 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/01/Lee---Company.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Aditya</p>
<p>Have you ever noticed that, when you are writing code in a text editor like VS code, it recognizes things like unmatched braces? And it also sometimes warns you, with an irritating red highlight, about the incorrect syntax that you have written? </p>
<p>If not, then think about it. That is after all a piece of code. How can you write code for such a task? What would be the underlying logic behind it? </p>
<p>These are the kinds of questions that you will face if you have to write a compiler for a programming language. Writing a compiler is not an easy task. It is bulky job that demands a significant amount of time and effort. </p>
<p>In this article, we are not going to talk about how to build compilers. But we will talk about a concept that is a core component of the compiler: Context Free Grammars.</p>
<h2 id="heading-introduction">Introduction</h2>
<p>All the questions we asked earlier represent a problem that is significant to compiler design called Syntax Analysis. As the name suggests, the challenge is to analyze the syntax and see if it is correct or not. This is where we use Context Free Grammars. A Context Free Grammar is a set of rules that define a language. </p>
<p>Here, I would like to draw a distinction between Context Free Grammars and grammars for natural languages like English. </p>
<p>Context Free Grammars or CFGs define a formal language. Formal languages work strictly under the defined rules and their sentences are not influenced by the context. And that's where it gets the name <em>context free</em>. </p>
<p>Languages such as English fall under the category of Informal Languages since they are affected by context. They have many other features which a CFG cannot describe.</p>
<p>Even though CFGs cannot describe the context in the natural languages, they can still define the syntax and structure of sentences in these languages. In fact, that is the reason why the CFGs were introduced in the first place. </p>
<p>In this article we will attempt to generate English sentences using CFGs. We will learn how to describe the sentence structure and write rules for it. To do this, we will use a JavaScript library called Tracery which will generate sentences on the basis of rules we defined for our grammar.</p>
<p>Before we dive into the code and start writing the rules for the grammar, let's just discuss some basic terms that we will use in our CFG.</p>
<p><strong>Terminals</strong>: These are the characters that make up the actual content of the final sentence. These can include words or letters depending on which of these is used as the basic building block of a sentence.</p>
<p>In our case we will use words as the basic building blocks of our sentences. So our terminals will include words such as "to", "from", "the", "car", "spaceship", "kittens" and so on.</p>
<p><strong>Non Terminals</strong>: These are also called variables. These act as a sub language within the language defined by the grammar. Non terminals are placeholders for the terminals. We can use non terminals to generate different patterns of terminal symbols.</p>
<p>In our case we will use these Non terminals to generate noun phrases, verb phrases, different nouns, adjectives, verbs and so on.</p>
<p><strong>Start Symbol</strong>: a start symbol is a special non terminal that represents the initial string that will be generated by the grammar.</p>
<p>Now that we know the terminology let's start learning about the grammatical rules. </p>
<p>While writing grammar rules, we will start by defining the set of terminals and a start state. As we learned before, that start symbol is a non-terminal. This means it will belong to the set of non-terminals. </p>
<pre><code>T: (<span class="hljs-string">"Monkey"</span>, <span class="hljs-string">"banana"</span>, <span class="hljs-string">"ate"</span>, <span class="hljs-string">"the"</span>)
<span class="hljs-attr">S</span>: Start state.
</code></pre><p>And the rules are:</p>
<pre><code>S --&gt; nounPhrase verbPhrase
nounPhrase --&gt; adj nounPhrase | adj noun
verbPhrase --&gt; verb nounPhrase
adjective  --&gt; the
noun --&gt; Monkey | banana
verb --&gt; ate
</code></pre><p>The above grammatical rules may seem somewhat cryptic at first. But if we look carefully, we can see a pattern that is being generated out of these rules. </p>
<p>A better way to think about the above rules is to visualise them in the form of a tree structure. In that tree we can put <em>S</em> in the root and <em>nounPhrase</em> and <em>verbPhrase</em> can be added as children of the root. We can proceed in the same way with <em>nounPhrase</em> and <em>verbPhrase</em> too. The tree will have terminals as its leaf nodes because that is where we end these derivations. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/01/parsetree.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>In the above image we can see that <em>S</em> (a nonterminal)  derives two non terminals <em>NP</em>(<em>nounPhrase</em>) and <em>VP</em>(<em>verbPhrase</em>). In the case of <em>NP</em>, it has derived two non terminals, <em>Adj</em> and <em>Noun</em>. </p>
<p>If you look at the grammar, <em>NP</em> could also have chosen <em>Adj</em> and <em>nounPhrase</em>. While generating text, these choices are made randomly. </p>
<p>And finally the leaf nodes have terminals which are written in the bold text. So if you move from left to right, you can see that a sentence is formed.</p>
<p>The term often used for this tree is a Parse Tree. We can create another parse tree for a different sentence generated by this grammar in a similar way. </p>
<p>Now let's proceed further to the code. As I mentioned earlier, we will use a JavaScript library called Tracery for text generation using CFGs. We will also write some code in HTML and CSS for the front-end part.</p>
<h2 id="heading-the-code">The Code</h2>
<p>Let's start by first getting the tracery library. You can clone the library from GitHub <a target="_blank" href="https://github.com/galaxykate/tracery">here</a>. I have also left the link to the GitHub repository by galaxykate at the end of the article.</p>
<p>Before we use the library we will have to import it. We can do this simply in an HTML file like this. </p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"tracery-master/js/vendor/jquery-1.11.2.min.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"tracery-master/tracery.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"tracery-master/js/grammars.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">'app.js'</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>

<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>I have added the cloned tracery file as a script in my HTML code. We will also have to add JQuery to our code because tracery depends on JQuery. Finally, I have added <em>app.js</em> which is the file where I will add rules for the grammar.</p>
<p>Once that is done, create a JavaScript file where we will define our grammar rules.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">var</span> rules = {
        <span class="hljs-string">"start"</span>: [<span class="hljs-string">"#NP# #VP#."</span>],
        <span class="hljs-string">"NP"</span>: [<span class="hljs-string">"#Det# #N#"</span>, <span class="hljs-string">"#Det# #N# that #VP#"</span>, <span class="hljs-string">"#Det# #Adj# #N#"</span>],
        <span class="hljs-string">"VP"</span>: [<span class="hljs-string">"#Vtrans# #NP#"</span>, <span class="hljs-string">"#Vintr#"</span>],
        <span class="hljs-string">"Det"</span>: [<span class="hljs-string">"The"</span>, <span class="hljs-string">"This"</span>, <span class="hljs-string">"That"</span>],
        <span class="hljs-string">"N"</span>: [<span class="hljs-string">"John Keating"</span>, <span class="hljs-string">"Bob Harris"</span>, <span class="hljs-string">"Bruce Wayne"</span>, <span class="hljs-string">"John Constantine"</span>, <span class="hljs-string">"Tony Stark"</span>, <span class="hljs-string">"John Wick"</span>, <span class="hljs-string">"Sherlock Holmes"</span>, <span class="hljs-string">"King Leonidas"</span>],
        <span class="hljs-string">"Adj"</span>: [<span class="hljs-string">"cool"</span>, <span class="hljs-string">"lazy"</span>, <span class="hljs-string">"amazed"</span>, <span class="hljs-string">"sweet"</span>],
        <span class="hljs-string">"Vtrans"</span>: [<span class="hljs-string">"computes"</span>, <span class="hljs-string">"examines"</span>, <span class="hljs-string">"helps"</span>, <span class="hljs-string">"prefers"</span>, <span class="hljs-string">"sends"</span>, <span class="hljs-string">"plays with"</span>, <span class="hljs-string">"messes up with"</span>],
        <span class="hljs-string">"Vintr"</span>: [<span class="hljs-string">"coughs"</span>, <span class="hljs-string">"daydreams"</span>, <span class="hljs-string">"whines"</span>, <span class="hljs-string">"slobbers"</span>, <span class="hljs-string">"appears"</span>, <span class="hljs-string">"disappears"</span>, <span class="hljs-string">"exists"</span>, <span class="hljs-string">"cries"</span>, <span class="hljs-string">"laughs"</span>]
    }
</code></pre>
<p>Here you will notice that the syntax for defining rules is not much different from how we defined our grammar earlier. There are very minor differences such as the way non-terminals are defined between the hash symbols. And also the way in which different derivations are written. Instead of using the "|" symbol for separating them, here we will put all the different derivations as different elements of an array. Other than that, we will use the semicolons instead of arrows to represent the transition. </p>
<p>This new grammar is a little more complicated than the one we defined earlier. This one includes many other things such as Determiners, Transitive Verbs and Intransitive Verbs. We do this to make the generated text look more natural. </p>
<p>Let's now call the tracery function "createGrammar" to create the grammar we just defined. </p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> grammar = tracery.createGrammar(rules);
</code></pre>
<p>This function will take the rules object and generate a grammar on the basis of these rules. After creating the grammar, we now want to generate some end result from it. To do that we will use a function called "flatten".</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> expansion = grammar.flatten(<span class="hljs-string">'#start#'</span>);
</code></pre>
<p>It will generate a random sentence based on the rules that we defined earlier. But let's not stop there. Let's also build a user interface for it. There's not much we will have to do for that part – we just need a button and some basic styles for the interface.</p>
<p>In the same HTML file where we added the libraries we will add some elements.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Weird Sentences<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"stylesheet"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"style.css"</span>/&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"https://fonts.googleapis.com/css?family=UnifrakturMaguntia&amp;display=swap"</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"stylesheet"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"https://fonts.googleapis.com/css?family=Harmattan&amp;display=swap"</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"stylesheet"</span>&gt;</span>

        <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"tracery-master/js/vendor/jquery-1.11.2.min.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"tracery-master/tracery.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"tracery-master/js/grammars.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">'app.js'</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">h1</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"h1"</span>&gt;</span>Weird Sentences<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"generate"</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"generate()"</span>&gt;</span>Give me a Sentence!<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"sentences"</span>&gt;</span>

        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>And finally we will add some styles to it.</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">body</span> {
    <span class="hljs-attribute">text-align</span>: center;
    <span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span>;
    <span class="hljs-attribute">font-family</span>: <span class="hljs-string">'Harmattan'</span>, sans-serif;
}

<span class="hljs-selector-id">#h1</span> {
    <span class="hljs-attribute">font-family</span>: <span class="hljs-string">'UnifrakturMaguntia'</span>, cursive;
    <span class="hljs-attribute">font-size</span>: <span class="hljs-number">4em</span>;
    <span class="hljs-attribute">background-color</span>: <span class="hljs-built_in">rgb</span>(<span class="hljs-number">37</span>, <span class="hljs-number">146</span>, <span class="hljs-number">235</span>);
    <span class="hljs-attribute">color</span>: white;
    <span class="hljs-attribute">padding</span>: .<span class="hljs-number">5em</span>;
    <span class="hljs-attribute">box-shadow</span>: <span class="hljs-number">1px</span> <span class="hljs-number">1px</span> <span class="hljs-number">1px</span> <span class="hljs-number">1px</span> <span class="hljs-built_in">rgb</span>(<span class="hljs-number">206</span>, <span class="hljs-number">204</span>, <span class="hljs-number">204</span>);
}

<span class="hljs-selector-id">#generate</span> {
    <span class="hljs-attribute">font-family</span>: <span class="hljs-string">'Harmattan'</span>, sans-serif;
    <span class="hljs-attribute">font-size</span>: <span class="hljs-number">2em</span>;
    <span class="hljs-attribute">font-weight</span>: bold;
    <span class="hljs-attribute">padding</span>: .<span class="hljs-number">5em</span>;
    <span class="hljs-attribute">margin</span>: .<span class="hljs-number">5em</span>;
    <span class="hljs-attribute">box-shadow</span>: <span class="hljs-number">1px</span> <span class="hljs-number">1px</span> <span class="hljs-number">1px</span> <span class="hljs-number">1px</span> <span class="hljs-built_in">rgb</span>(<span class="hljs-number">206</span>, <span class="hljs-number">204</span>, <span class="hljs-number">204</span>);
    <span class="hljs-attribute">background-color</span>: <span class="hljs-built_in">rgb</span>(<span class="hljs-number">255</span>, <span class="hljs-number">0</span>, <span class="hljs-number">64</span>);
    <span class="hljs-attribute">color</span>: white;
    <span class="hljs-attribute">border</span>: none;
    <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">2px</span>;
    <span class="hljs-attribute">outline</span>: none;
}

<span class="hljs-selector-id">#sentences</span> <span class="hljs-selector-tag">p</span> {
    <span class="hljs-attribute">box-shadow</span>: <span class="hljs-number">1px</span> <span class="hljs-number">1px</span> <span class="hljs-number">1px</span> <span class="hljs-number">1px</span> <span class="hljs-built_in">rgb</span>(<span class="hljs-number">206</span>, <span class="hljs-number">204</span>, <span class="hljs-number">204</span>);
    <span class="hljs-attribute">margin</span>: <span class="hljs-number">2em</span>;
    <span class="hljs-attribute">margin-left</span>: <span class="hljs-number">15em</span>;
    <span class="hljs-attribute">margin-right</span>: <span class="hljs-number">15em</span>;
    <span class="hljs-attribute">padding</span>: <span class="hljs-number">2em</span>;
    <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">2px</span>;
    <span class="hljs-attribute">font-size</span>: <span class="hljs-number">1.5em</span>;
}
</code></pre>
<p>We will also have to add some more JavaScript to manipulate the interface.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> sentences = []
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">generate</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">var</span> data = {
        <span class="hljs-string">"start"</span>: [<span class="hljs-string">"#NP# #VP#."</span>],
        <span class="hljs-string">"NP"</span>: [<span class="hljs-string">"#Det# #N#"</span>, <span class="hljs-string">"#Det# #N# that #VP#"</span>, <span class="hljs-string">"#Det# #Adj# #N#"</span>],
        <span class="hljs-string">"VP"</span>: [<span class="hljs-string">"#Vtrans# #NP#"</span>, <span class="hljs-string">"#Vintr#"</span>],
        <span class="hljs-string">"Det"</span>: [<span class="hljs-string">"The"</span>, <span class="hljs-string">"This"</span>, <span class="hljs-string">"That"</span>],
        <span class="hljs-string">"N"</span>: [<span class="hljs-string">"John Keating"</span>, <span class="hljs-string">"Bob Harris"</span>, <span class="hljs-string">"Bruce Wayne"</span>, <span class="hljs-string">"John Constantine"</span>, <span class="hljs-string">"Tony Stark"</span>, <span class="hljs-string">"John Wick"</span>, <span class="hljs-string">"Sherlock Holmes"</span>, <span class="hljs-string">"King Leonidas"</span>],
        <span class="hljs-string">"Adj"</span>: [<span class="hljs-string">"cool"</span>, <span class="hljs-string">"lazy"</span>, <span class="hljs-string">"amazed"</span>, <span class="hljs-string">"sweet"</span>],
        <span class="hljs-string">"Vtrans"</span>: [<span class="hljs-string">"computes"</span>, <span class="hljs-string">"examines"</span>, <span class="hljs-string">"helps"</span>, <span class="hljs-string">"prefers"</span>, <span class="hljs-string">"sends"</span>, <span class="hljs-string">"plays with"</span>, <span class="hljs-string">"messes up with"</span>],
        <span class="hljs-string">"Vintr"</span>: [<span class="hljs-string">"coughs"</span>, <span class="hljs-string">"daydreams"</span>, <span class="hljs-string">"whines"</span>, <span class="hljs-string">"slobbers"</span>, <span class="hljs-string">"appears"</span>, <span class="hljs-string">"disappears"</span>, <span class="hljs-string">"exists"</span>, <span class="hljs-string">"cries"</span>, <span class="hljs-string">"laughs"</span>]
    }

    <span class="hljs-keyword">let</span> grammar = tracery.createGrammar(data);
    <span class="hljs-keyword">let</span> expansion = grammar.flatten(<span class="hljs-string">'#start#'</span>);

    sentences.push(expansion);

    printSentences(sentences);
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">printSentences</span>(<span class="hljs-params">sentences</span>) </span>{
    <span class="hljs-keyword">let</span> textBox = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"sentences"</span>);
    textBox.innerHTML = <span class="hljs-string">""</span>;
    <span class="hljs-keyword">for</span>(<span class="hljs-keyword">let</span> i=sentences.length<span class="hljs-number">-1</span>; i&gt;=<span class="hljs-number">0</span>; i--) {
        textBox.innerHTML += <span class="hljs-string">"&lt;p&gt;"</span>+sentences[i]+<span class="hljs-string">"&lt;/p&gt;"</span>
    }
}
</code></pre>
<p>Once you have finished writing the code, run your HTML file. It should look something like this.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/01/ws2.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Every time you click the red button it will generate a sentence. Some of these sentences might not make any sense. This is because, as I said earlier, CFGs cannot describe the context and some other features that natural languages possess. It is used only to define the syntax and structure of the sentences. </p>
<p>You can check out the live version of this <a target="_blank" href="https://aditya2000.github.io/weird-sentences/">here</a>.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>If you have made it this far, I highly appreciate your resilience. It might be a new concept for some of you, and others might have learnt about it in their college courses. But still, Context Free Grammars have interesting applications that range widely from Computer Science to Linguistics. </p>
<p>I have tried my best to present the main ideas of CFGs here, but there is a lot more that you can learn about them. Here I have left links to some great resources: </p>
<ul>
<li><a target="_blank" href="https://youtu.be/C3EwsSNJeOE">Context Free Grammars</a> by Daniel Shiffman.</li>
<li><a target="_blank" href="https://youtu.be/R_OVyFrBhiU">Context Free Grammars Examples</a> by Fullstack Academy</li>
<li><a target="_blank" href="https://github.com/galaxykate/tracery">Tracery</a> by Galaxykate</li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Exploring the Linguistics Behind Regular Expressions ]]>
                </title>
                <description>
                    <![CDATA[ By Alaina Kafkes How a linguistic breakthrough ended up in code _Image Credit: [xkcd](https://xkcd.com/" rel="noopener" target="blank" title=") Regular expressions inspire fear in new and experienced programmers alike. When I first saw a regular exp... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/exploring-the-linguistics-behind-regular-expressions-596fab41146/</link>
                <guid isPermaLink="false">66c34a264f1fc448a3678fff</guid>
                
                    <category>
                        <![CDATA[ computational linguistics ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Computer Science ]]>
                    </category>
                
                    <category>
                        <![CDATA[ linguistics ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Regex ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Regular Expressions ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Mon, 20 Nov 2017 15:38:09 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*w-_7zxjx3gZgx_rLNVq60A.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Alaina Kafkes</p>
<h4 id="heading-how-a-linguistic-breakthrough-ended-up-in-code">How a linguistic breakthrough ended up in code</h4>
<p><img src="https://cdn-media-1.freecodecamp.org/images/-X06qYZoSEvRExXkwcADhu5kjKD64s6zg80F" alt="Image" width="611" height="203" loading="lazy">
_Image Credit: [xkcd](https://xkcd.com/" rel="noopener" target="<em>blank" title=")</em></p>
<p>Regular expressions inspire fear in new and experienced programmers alike. When I first saw a regular expression — often abbreviated as “regex” — I remember feeling dizzy from looking at the litany of parentheses, asterisks, letters, and numbers. Regular expressions seemed nonsensical, impenetrable.</p>
<p>I expected regular expressions to crop up again in my upper-level computer science coursework — maybe by then I’d finally feel ready to tackle them — but I encountered them in an introductory class that I had put off until my senior year. The purpose of this course was to draw students who had never written a line of code into CS by introducing them to concepts like cryptography, human-computer interaction, machine learning — you know, only the latest and greatest of tech buzzwords.</p>
<p>I didn’t attend more than a handful of lectures, but one of the assignments stuck with me. I had to write an essay about a famous computer scientist or academic whose work impacted computer science. I chose Noam Chomsky.</p>
<p>Little did I know that learning about Chomsky would drag me down a rabbit hole back to regular expressions, and then magically cast regular expressions into something that fascinated me. What enchanted me about regular expressions was the homonymous linguistic concept that powered them.</p>
<p>I hope to spellbind you, too, with the linguistics behind regular expressions, a a backstory unknown to most programmers. Though I won’t teach you how to use regular expressions in any particular programming language, I hope that my linguistic introduction will inspire you to dive deeper into how regular expressions work in your programming language of choice.</p>
<p>To begin, let’s return to Chomsky: what does he have to do with regular expressions? Hell, what does he even have to do with computer science?</p>
<h3 id="heading-a-computer-scientist-by-accident">A Computer Scientist By Accident</h3>
<p>Wikipedia christens <a target="_blank" href="https://en.wikipedia.org/wiki/Noam_Chomsky">Noam Chomsky</a> as a linguist, philosopher, cognitive scientist, historian, social critic, and political activist, but <em>not</em> as a computer scientist. Because he is so highly regarded in all of these fields, his indirect contributions to the field of computer science often fall by the wayside.</p>
<p>The more I researched Chomsky’s academic work, the more accidental Chomsky’s foray into computing seemed. This affirmed my belief that all fields — even those that appear disparate from computer science — have something to offer to computing and the tech industry.</p>
<p>His contributions to the field of linguistics in particular exemplify the impact of interdisciplinary research on computer science. The Chomsky hierarchy transformed the code that computer scientists, software engineers, and hobbyists write today.</p>
<p>Yes, it was this hierarchy that brought regular expressions to computer science. But, before we can understand the jump from Chomsky to regular expressions, I’ll outline the Chomsky hierarchy.</p>
<h3 id="heading-linguistic-law-amp-order">Linguistic Law &amp; Order</h3>
<p>The <a target="_blank" href="https://en.wikipedia.org/wiki/Chomsky_hierarchy"><strong>Chomsky hierarchy</strong></a> is an ordering of <a target="_blank" href="https://en.wikipedia.org/wiki/Formal_grammar"><strong>formal grammars</strong></a> — think syntactic rules for <a target="_blank" href="http://interactivepython.org/courselib/static/thinkcspy/GeneralIntro/FormalandNaturalLanguages.html"><strong>formal languages</strong></a> — such that each grammar exists as a <a target="_blank" href="http://mathworld.wolfram.com/ProperSubset.html">proper subset</a> of the grammars above it in the hierarchy. Some formal languages have stricter grammars than others, so Chomsky sought to organize formal grammars into his eponymous hierarchy.</p>
<p>I briefly mentioned that formal grammars are syntactic rules: rules that give all possible valid phrases for a given formal language. Grammars provide the rules that build languages. In linguist-speak, a language’s formal grammar provides a framework with which <strong>nonterminals</strong> (input or intermediate string values) can be converted into <strong>terminals</strong> (output string values).</p>
<p>To elucidate this new vocabulary, I’ll walk through an example of converting a set of nonterminals into terminals using a made-up formal grammar. Let’s say that our pretend formal language, <a target="_blank" href="http://harrypotter.wikia.com/wiki/Parseltongue">Parseltongue</a>, has the following formal grammar:</p>
<ul>
<li>Terminals: {s, sh, ss}</li>
<li>Nonterminals: {snake, I, am}</li>
<li>Production rules: {I → sh, am → s, snake → ss}</li>
</ul>
<p>Using the production rules, I can convert the input sentence “I am snake” into “sh s ss.” This conversion happens piece by piece: “I am snake” → “sh am snake” → “sh s snake” → “sh s ss.”</p>
<p>As my Parseltongue example illustrates, formal grammars parse strings of nonterminals into terminal-only strings — grammatically correct phrases. But formal grammars act not only as <em>generators</em> of a language, but also <em>recognizers</em> of whether a string fits the formal grammar. Whereas the example string “I am a snake” can be fully converted into terminals, the string “I am not a snake” cannot be written in Parseltongue because the nonterminal “not” cannot be translated into a Parseltongue terminal.</p>
<p>To re-emphasize something I stated earlier: formal grammars generate formal languages. That means that, by creating a hierarchy of formal grammars, Chomsky also categorized languages themselves.</p>
<p>With that sobering introduction, let’s look at the four formal grammars in Chomsky’s hierarchy. From most to least strict, they are:</p>
<ul>
<li><strong>Regular grammars</strong>, which retain no past state knowledge from input string to output string</li>
<li><strong>Context-free grammars</strong>, which retain only recent state knowledge from input string to output string</li>
<li><strong>Context-sensitive grammars</strong>, which keep all past state knowledge from input string to output string</li>
<li><strong>Unrestricted</strong> (or <strong>recursively enumerable</strong>) <strong>grammars</strong>, which have all state knowledge and thus can create every output string imaginable from a given input string</li>
</ul>
<p>What is this “state knowledge” that I speak of? Think of knowledge in terms of <a target="_blank" href="https://en.wikipedia.org/wiki/Scope_(computer_science)">scope</a>. Regular grammars, for example, have no knowledge of the string’s past states in their “scope” in the process of converting an input string into an output string. This suggests that once the grammar makes an individual conversion of nonterminal to terminal (plus a series of zero or more nonterminals), the grammar “forgets” the previous state of the string.</p>
<p>On the other hand, unrestricted grammars hold onto every possible state of the string-in-translation. Context-free and context-sensitive grammars fall somewhere in the middle.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/DixBS4lQwkJv5Qdc7tSrQMsVjdQdevpMfyLh" alt="Image" width="800" height="577" loading="lazy"></p>
<p>If you’re looking for a more detailed explanation of the grammars in the Chomsky hierarchy, you’ll have to take a peek at <a target="_blank" href="https://en.wikipedia.org/wiki/Automata_theory">automata theory</a>. I’ll focus on the grammar that brings us back to regular expressions, fittingly called the regular grammar.</p>
<h3 id="heading-on-the-regular-expressions">On the Regular Expressions</h3>
<p>Regular expressions and regular grammars are equivalent. They communicate the same set of syntactic rules, albeit using different formalisms, and both produce the same regular languages.</p>
<p>In linguistics, a <strong>regular expression</strong> is recursively defined as follows:</p>
<ul>
<li>The empty set is a regular expression.</li>
<li>The empty string is a regular expression.</li>
<li>For any character x in the input alphabet, x is a regular expression that produces the regular language {x}.</li>
<li><strong>Alternation</strong>: If x and y are regular expressions, then x | y is a regular expression. For example, the regular expression <code>0|1</code> produces the regular language <code>{0,1}</code>.</li>
<li><strong>Concatenation</strong>: If x and y are regular expressions, then x • y is a regular expression. For example, the regular expression <code>0•1</code> produces the regular language <code>{01}</code>.</li>
<li><strong>Repetition</strong> (also known as <strong>Kleene star</strong>): If x and y are regular expressions, then x<em> is a regular expression. For example, the regular language `0•1</em><code>produces the regular language</code>{0, 01, 011, 0111, ...}`, ad infinitum.</li>
</ul>
<p>A regular grammar is composed of rules like those of Parseltongue. Just as a regular grammar can be utilized to parse an input string into an output string, a regular expression converts strings quite similarly. You can see examples of this parsing for the alternation, concatenation, and repetition operations — or, to use my prior analogy, rules — that regular expressions adopt.</p>
<p>Let’s return to our friend Noam Chomsky for a moment. According to his hierarchy of grammars, regular grammars retain no information about intermediate steps in converting from an input string to an output string. What does this tell us about regular expressions?</p>
<p>The “forgetfulness” of regular grammars implies that translations in one part of the string do not impact how the other nonterminals in the string are translated in future steps. There is no coordination between different parts of the string in the creation of the output string.</p>
<p>Looking at the linguistics behind regular grammars gives us insight into why programmers first brought regular expressions into code. Although I’ve only discussed formal grammars as generators and recognizers of language, the fact that regular grammars convert input string to output string piece by piece makes them <em>pattern-matchers</em>. In programming, regular expressions use production rules to convert an input string — a pattern — into a regular language — a set of strings that match that pattern.</p>
<p>But I would have never written this blog post if programming language creators implemented regular expressions exactly as they are defined in the field of linguistics. Computational regular expressions are a far cry from their linguistic precursor, but the linguistic regular expressions that I covered provide a useful framework for understanding regular expressions in code.</p>
<h3 id="heading-two-regular-expressions-both-alike-in-dignity">Two Regular Expressions, Both Alike in Dignity</h3>
<p>Hereafter, I will use the term <strong>regular expression</strong> to mean a <em>linguistic</em> regular expression and the term <strong>regex</strong> to signify a <em>programmatic</em> regular expression. In the wild, both linguistic and programmatic regular expressions are referred to as “regular expressions” even though they are quite different from one another — how confusing!</p>
<p>The difference between regular expressions and regexes stems from how they are used. Regular expressions — or regular grammars — are part of <a target="_blank" href="https://en.wikipedia.org/wiki/Formal_language">formal language <em>theory</em></a>, which exists to <em>describe</em> shared elements of <strong>natural languages</strong> — languages that evolved over time without human premeditation. <em>Linguists</em> use regular expressions for theoretical purposes, like the categorization of formal grammars in the Chomsky hierarchy. Regular expressions help linguists understand the languages that humans speak.</p>
<p>Regexes, on the other hand, are utilized by <em>everyday programmers</em> who want to <em>search</em> for strings that <em>match</em> a given pattern. While regular expressions are theoretical, regexes are pragmatic. Programming languages are <strong>formal languages</strong>: languages designed by people (here, programmers) for specific purposes. As you might imagine, programming language creators augmented the functionality of regexes in code. Let’s examine these enhancements.</p>
<p>Remember that regular expressions have three operations: alternation, concatenation, and repetition. I’m no regex expert — regexpert? — but all it takes is a peek at the <a target="_blank" href="https://en.wikipedia.org/wiki/Regular_expression">regular expression Wikipedia page</a> to notice that regexes implement more than just three operations.</p>
<p>For example, using <a target="_blank" href="https://www.regular-expressions.info/posix.html">POSIX regex syntax</a>, the pattern <code>.ork</code> matches all four-character strings that end with the three characters “ork.” That period is more powerful than simple alternation, concatenation, and repetition, right?</p>
<p>Nope. Truth be told, even the fanciest of regex <a target="_blank" href="https://en.wikipedia.org/wiki/Metacharacter"><strong>metacharacters</strong></a> — characters that invoke a regex operation — derive from regular expression operations. Assuming that the twenty-six lowercase letters of the alphabet are the only characters in the regular grammar, the regex pattern <code>.ork</code> could be written using only regular expression operations as <code>[a|b|c|...|z]ork</code>.</p>
<p>Though the sheer volume of metacharacters suggests that regex has a more powerful set of operations than regular expressions themselves, metacharacters are merely shortcuts for various permutations of the operations that define regular expressions. Regex metacharacters provide a programmer-friendly abstraction for common combinations of alternation, concatenation, and repetition.</p>
<p>So far, I’ve portrayed regexes as regular expressions with amazing shortcuts and clear-cut use cases. However, as you may recall from Chomsky’s hierarchy, regular grammars have the strictest rules and no scope. Luckily, regexes have a little more leeway than their linguistic precursor, thereby bestowing them with more practical power.</p>
<h3 id="heading-breaking-the-regular-grammar-rules">Breaking the Regular Grammar Rules</h3>
<p>Recall that, according to the the Chomsky hierarchy, regular grammars retain no knowledge in converting an input string to an output string. Since regular expressions are equivalent to regular grammars, this means that regular expressions also have no memory of the intermediate states of a string as it changed from input to output. It also means that translating a nonterminal in one part of a regular expressions has no bearing on the translation of a nonterminal in another part of the expression.</p>
<p>For regexes, it’s a different story. Regexes violate this key regular grammar characteristic by supporting the ability to backreference. <strong>Backreferencing</strong> allows the programmer to parenthetically separate a subsection of a regular expression and refer to it using a metacharacter. To give an example, the pattern <code>(la)\1</code> matches “lala” by employing the <code>\1</code> metacharacter to repeat the search for “la.”</p>
<p>Because different parts of the string cannot influence one another in regular expressions, backreferencing gives regexes a lot more power than their predecessor. More importantly, backreferencing facilitates practical uses of regex such as searching for typos in which the same word was accidentally typed twice in a row. Pragmatism gives insight into why regular expressions were tweaked to create regexes in programming.</p>
<p>Another feature that increases the functionality of regex is the ability to alter the greediness of the matching. Different <strong>quantifiers</strong> — categories of regex patterns — can look similar but match drastically different parts of a string. A <strong>greedy quantifier</strong> (<em>) will attempt to match as much of the string as possible, whereas a <strong>reluctant quantifier</strong> (?) will try to match the minimum amount of characters in the string. Given the string “abcorgi,” the pattern `.</em>corgi<code>would match the entire string but the pattern</code>.?corgi` would only match “bcorgi.”</p>
<p>A <strong>possessive quantifier</strong> (+) also attempts to match as much of the string as possible, but, unlike the greedy quantifier, it will not backtrack to previous characters in the string in order to find the largest possible match. Given the string “abcorgi,” the patterns <code>.*corgi</code> and <code>.+corgi</code> would match the entire string. Though possessive and greedy qualifiers will often produce the same result, possessive qualifiers tend to be more efficient because they avoid backtracking.</p>
<p>Because quantifiers are metacharacters, they can technically be built from alternation, concatenation, and repetition: the three operations of regular expressions. However, quantifiers create a simple abstraction that allows programmers to quickly specify what type of match they would like.</p>
<h3 id="heading-conclusion-amp-further-reading">Conclusion &amp; Further Reading</h3>
<p>What a journey we’ve undertaken! We learned about Chomsky and his eponymous hierarchy, then dove deeper into regular grammars. From regular grammars, we explored the linguistic definition of a regular expression. Finally, we used the differences between regular expressions and regexes to motivate how programmers use regex today.</p>
<p>Although I trace the history of regular expressions from Chomsky to modern programming languages, this blog post is not the end of the regex story. If you’d like to learn more about linguistic and computational regular expressions, I have some motivating questions for you.</p>
<ul>
<li>What is automata theory and how does it relate to the Chomsky hierarchy?</li>
<li>How are regex implemented? What are the tradeoffs of various regex algorithms?</li>
<li>When is it appropriate to use regexes instead of built-in string match and manipulation libraries?</li>
</ul>
<p>I also have a list of resources that I used to study up on the linguistic and computational elements of regular expressions. Happy regex-ing!</p>
<ul>
<li><a target="_blank" href="https://www.regular-expressions.info/">Regular-Expressions.info</a></li>
<li><a target="_blank" href="https://en.wikipedia.org/wiki/Regular_expression">Wikipedia: Regular Expressions</a></li>
<li><a target="_blank" href="https://stackoverflow.com/questions/8398030/chomsky-hierarchy-in-plain-english">StackOverflow: Chomsky Hierarchy in plain English</a></li>
<li><a target="_blank" href="https://www.amazon.com/Introduction-Automata-Theory-Languages-Computation/dp/0321455363"><em>Introduction to Automata Theory, Languages, and Computation</em></a> by Hopcroft et al.</li>
<li><a target="_blank" href="https://cs.stackexchange.com/questions/45755/difference-between-regular-expression-and-grammar-in-automata">StackOverflow: Difference between regular expression and grammar in automata</a></li>
<li><a target="_blank" href="http://interactivepython.org/courselib/static/thinkcspy/GeneralIntro/FormalandNaturalLanguages.html">How to Think like a Computer Scientist: Formal and Natural Languages</a></li>
<li><a target="_blank" href="https://docs.oracle.com/javase/tutorial/essential/regex/quant.html">Oracle’s Java Tutorials: Quantifiers</a></li>
<li><a target="_blank" href="https://cs.stackexchange.com/questions/53397/compare-regex-in-programming-languages-with-regular-expression-from-automata-for?rq=1">StackOverflow: Compare regex in programming languages with regular expression from automata/formal language</a></li>
<li><a target="_blank" href="https://www.quora.com/How-are-regular-expressions-implemented">Quora: How are regular expressions implemented?</a></li>
</ul>
<p><em>Enjoy what you read? Spread the love by liking and sharing this piece. Have thoughts or questions? Reach out to me on <a target="_blank" href="https://twitter.com/alainakafkes">Twitter</a> or in the comments below. Thank you <a target="_blank" href="https://www.freecodecamp.org/news/exploring-the-linguistics-behind-regular-expressions-596fab41146/undefined">Miles Hinson</a> for proofreading this piece!</em></p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
