<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Grammar on Tarragon</title><link>https://tarrragon.github.io/blog/tags/grammar/</link><description>Recent content in Grammar on Tarragon</description><generator>Hugo -- gohugo.io</generator><language>zh-TW</language><copyright>Tarragon (CC BY 4.0)</copyright><lastBuildDate>Thu, 14 May 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://tarrragon.github.io/blog/tags/grammar/index.xml" rel="self" type="application/rss+xml"/><item><title>BNF（Backus-Naur Form）</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/bnf/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/bnf/</guid><description>&lt;p>BNF（Backus-Naur Form）的核心概念是「&lt;strong>用產生式規則描述一個語言裡哪些字串合法&lt;/strong>」。它常用在程式語言、資料格式、parser 與 structured output grammar，讓人跟工具都能用同一份規則理解合法語法。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>BNF 是 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/grammar/" data-link-title="Grammar" data-link-desc="描述合法字串形狀的形式規則，在 structured output 中用來限制 LLM 每一步可輸出的 token">grammar&lt;/a> 的一種表示法，特別適合描述 context-free grammar。規則左邊是非終結符，右邊是它可以展開成的符號組合；終結符是實際會出現在字串中的 token，非終結符是中間抽象節點。&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">&amp;lt;expr&amp;gt; ::= &amp;lt;term&amp;gt; | &amp;lt;expr&amp;gt; &amp;#34;+&amp;#34; &amp;lt;term&amp;gt;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">&amp;lt;term&amp;gt; ::= &amp;lt;number&amp;gt; | &amp;#34;(&amp;#34; &amp;lt;expr&amp;gt; &amp;#34;)&amp;#34;&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>這段規則表示 expression 可以是 term，也可以是 expression 加 term；term 可以是 number，也可以是括號包住的 expression。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>看到 &lt;code>::=&lt;/code>、&lt;code>&amp;lt;name&amp;gt;&lt;/code>、多個展開選項，就是 BNF 或 BNF-like grammar。LLM structured output 文章裡提到 BNF，通常是在說「把合法輸出格式寫成形式語法，推論時用它限制生成」。llama.cpp 的 GBNF、部分 grammar engine 與 parser 文件都會使用類似記法。&lt;/p>
&lt;p>BNF 的限制是它描述語法，不描述語意。它能表示「括號必須成對」「欄位順序合法」，但不能直接表示「日期必須晚於今天」「使用者必須有權限讀這筆資料」這類外部約束。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>BNF 適合拿來讀懂 grammar-constrained sampling 的規則形狀。實作時要確認你使用的引擎支援的是標準 BNF、EBNF、GBNF，還是自家 dialect；不同 dialect 的 optional、repeat、token escaping 寫法會不同。下一步路由是 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/grammar/" data-link-title="Grammar" data-link-desc="描述合法字串形狀的形式規則，在 structured output 中用來限制 LLM 每一步可輸出的 token">Grammar&lt;/a> 與 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/lark-grammar/" data-link-title="Lark Grammar" data-link-desc="Lark parser 使用的 EBNF-like grammar 格式，常被 structured output 工具拿來描述自訂輸出語法">Lark Grammar&lt;/a>。&lt;/p></description><content:encoded><![CDATA[<p>BNF（Backus-Naur Form）的核心概念是「<strong>用產生式規則描述一個語言裡哪些字串合法</strong>」。它常用在程式語言、資料格式、parser 與 structured output grammar，讓人跟工具都能用同一份規則理解合法語法。</p>
<h2 id="概念位置">概念位置</h2>
<p>BNF 是 <a href="/blog/llm/knowledge-cards/grammar/" data-link-title="Grammar" data-link-desc="描述合法字串形狀的形式規則，在 structured output 中用來限制 LLM 每一步可輸出的 token">grammar</a> 的一種表示法，特別適合描述 context-free grammar。規則左邊是非終結符，右邊是它可以展開成的符號組合；終結符是實際會出現在字串中的 token，非終結符是中間抽象節點。</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">&lt;expr&gt; ::= &lt;term&gt; | &lt;expr&gt; &#34;+&#34; &lt;term&gt;
</span></span><span class="line"><span class="ln">2</span><span class="cl">&lt;term&gt; ::= &lt;number&gt; | &#34;(&#34; &lt;expr&gt; &#34;)&#34;</span></span></code></pre></div><p>這段規則表示 expression 可以是 term，也可以是 expression 加 term；term 可以是 number，也可以是括號包住的 expression。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>看到 <code>::=</code>、<code>&lt;name&gt;</code>、多個展開選項，就是 BNF 或 BNF-like grammar。LLM structured output 文章裡提到 BNF，通常是在說「把合法輸出格式寫成形式語法，推論時用它限制生成」。llama.cpp 的 GBNF、部分 grammar engine 與 parser 文件都會使用類似記法。</p>
<p>BNF 的限制是它描述語法，不描述語意。它能表示「括號必須成對」「欄位順序合法」，但不能直接表示「日期必須晚於今天」「使用者必須有權限讀這筆資料」這類外部約束。</p>
<h2 id="設計責任">設計責任</h2>
<p>BNF 適合拿來讀懂 grammar-constrained sampling 的規則形狀。實作時要確認你使用的引擎支援的是標準 BNF、EBNF、GBNF，還是自家 dialect；不同 dialect 的 optional、repeat、token escaping 寫法會不同。下一步路由是 <a href="/blog/llm/knowledge-cards/grammar/" data-link-title="Grammar" data-link-desc="描述合法字串形狀的形式規則，在 structured output 中用來限制 LLM 每一步可輸出的 token">Grammar</a> 與 <a href="/blog/llm/knowledge-cards/lark-grammar/" data-link-title="Lark Grammar" data-link-desc="Lark parser 使用的 EBNF-like grammar 格式，常被 structured output 工具拿來描述自訂輸出語法">Lark Grammar</a>。</p>
]]></content:encoded></item><item><title>Grammar</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/grammar/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/grammar/</guid><description>&lt;p>Grammar（語法規則）的核心概念是「&lt;strong>用形式化規則描述哪些字串是合法輸出&lt;/strong>」。在 LLM structured output 裡，grammar 是 parser / decoder 可以執行的規則集合，用來判斷 JSON、SQL、DSL、表達式或自訂格式是否符合預期形狀——此處的 grammar 指形式語法，而非英文文法。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Grammar 位在格式定義層，常被 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/constrained-decoding/" data-link-title="Constrained Decoding" data-link-desc="推論時用 grammar 強制 LLM 輸出符合特定格式（JSON / regex / CFG）的 sampling 機制、把不合法 token 的機率歸零">constrained decoding&lt;/a> 編譯成 token mask。它跟 schema 的差異在表達方式：schema 常描述資料結構與欄位限制，grammar 描述字串如何從符號規則生成；JSON Schema 適合物件欄位，grammar 適合自訂語言、查詢語法、括號結構與特定文字格式。&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">grammar 規則 → parser / decoder 編譯
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl"> ↓
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">每個生成位置算出合法 token
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl"> ↓
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl">不合法 token 被 mask 掉&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>看到 &lt;code>expr: term (&amp;quot;+&amp;quot; term)*&lt;/code>、&lt;code>start: object&lt;/code>、&lt;code>&amp;lt;json&amp;gt; ::= ...&lt;/code> 這類規則就是 grammar。例子是讓模型只輸出簡化查詢語言：欄位只能是 &lt;code>status&lt;/code> / &lt;code>owner&lt;/code>，運算子只能是 &lt;code>=&lt;/code> / &lt;code>in&lt;/code>，字串必須加引號；grammar 可以把非法查詢擋在生成階段。&lt;/p>
&lt;p>Grammar 的邊界是語意與外部狀態。它可以限制語法合法，卻不能知道 &lt;code>owner = &amp;quot;alice&amp;quot;&lt;/code> 是否真有這個使用者，也不能判斷查詢是否符合權限；這些仍要交給 validator、authorization 與業務規則。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>需要自訂輸出格式時，先判斷格式是資料結構還是小語言：物件欄位優先用 JSON Schema，小語言或查詢語法才用 grammar。下一步路由是：需要語法表示法讀 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/bnf/" data-link-title="BNF（Backus-Naur Form）" data-link-desc="用遞迴產生式描述語法的經典記法，是 CFG、parser 與 grammar-constrained sampling 常見的基礎表示">BNF&lt;/a> 或 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/lark-grammar/" data-link-title="Lark Grammar" data-link-desc="Lark parser 使用的 EBNF-like grammar 格式，常被 structured output 工具拿來描述自訂輸出語法">Lark Grammar&lt;/a>；需要應用層自訂語言讀 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/dsl/" data-link-title="DSL（Domain-Specific Language）" data-link-desc="為特定業務或技術領域設計的小語言，在 LLM 應用中常作為可解析、可驗證、可執行的中介輸出">DSL&lt;/a>。&lt;/p></description><content:encoded><![CDATA[<p>Grammar（語法規則）的核心概念是「<strong>用形式化規則描述哪些字串是合法輸出</strong>」。在 LLM structured output 裡，grammar 是 parser / decoder 可以執行的規則集合，用來判斷 JSON、SQL、DSL、表達式或自訂格式是否符合預期形狀——此處的 grammar 指形式語法，而非英文文法。</p>
<h2 id="概念位置">概念位置</h2>
<p>Grammar 位在格式定義層，常被 <a href="/blog/llm/knowledge-cards/constrained-decoding/" data-link-title="Constrained Decoding" data-link-desc="推論時用 grammar 強制 LLM 輸出符合特定格式（JSON / regex / CFG）的 sampling 機制、把不合法 token 的機率歸零">constrained decoding</a> 編譯成 token mask。它跟 schema 的差異在表達方式：schema 常描述資料結構與欄位限制，grammar 描述字串如何從符號規則生成；JSON Schema 適合物件欄位，grammar 適合自訂語言、查詢語法、括號結構與特定文字格式。</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">grammar 規則 → parser / decoder 編譯
</span></span><span class="line"><span class="ln">2</span><span class="cl">  ↓
</span></span><span class="line"><span class="ln">3</span><span class="cl">每個生成位置算出合法 token
</span></span><span class="line"><span class="ln">4</span><span class="cl">  ↓
</span></span><span class="line"><span class="ln">5</span><span class="cl">不合法 token 被 mask 掉</span></span></code></pre></div><h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>看到 <code>expr: term (&quot;+&quot; term)*</code>、<code>start: object</code>、<code>&lt;json&gt; ::= ...</code> 這類規則就是 grammar。例子是讓模型只輸出簡化查詢語言：欄位只能是 <code>status</code> / <code>owner</code>，運算子只能是 <code>=</code> / <code>in</code>，字串必須加引號；grammar 可以把非法查詢擋在生成階段。</p>
<p>Grammar 的邊界是語意與外部狀態。它可以限制語法合法，卻不能知道 <code>owner = &quot;alice&quot;</code> 是否真有這個使用者，也不能判斷查詢是否符合權限；這些仍要交給 validator、authorization 與業務規則。</p>
<h2 id="設計責任">設計責任</h2>
<p>需要自訂輸出格式時，先判斷格式是資料結構還是小語言：物件欄位優先用 JSON Schema，小語言或查詢語法才用 grammar。下一步路由是：需要語法表示法讀 <a href="/blog/llm/knowledge-cards/bnf/" data-link-title="BNF（Backus-Naur Form）" data-link-desc="用遞迴產生式描述語法的經典記法，是 CFG、parser 與 grammar-constrained sampling 常見的基礎表示">BNF</a> 或 <a href="/blog/llm/knowledge-cards/lark-grammar/" data-link-title="Lark Grammar" data-link-desc="Lark parser 使用的 EBNF-like grammar 格式，常被 structured output 工具拿來描述自訂輸出語法">Lark Grammar</a>；需要應用層自訂語言讀 <a href="/blog/llm/knowledge-cards/dsl/" data-link-title="DSL（Domain-Specific Language）" data-link-desc="為特定業務或技術領域設計的小語言，在 LLM 應用中常作為可解析、可驗證、可執行的中介輸出">DSL</a>。</p>
]]></content:encoded></item><item><title>Lark Grammar</title><link>https://tarrragon.github.io/blog/llm/knowledge-cards/lark-grammar/</link><pubDate>Thu, 14 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/llm/knowledge-cards/lark-grammar/</guid><description>&lt;p>Lark grammar 的核心概念是「&lt;strong>Lark parser 使用的一種 EBNF-like 語法描述格式&lt;/strong>」。在 LLM structured output 文件中看到 lark grammar，通常是在說某個工具用 Lark 風格規則描述合法輸出，再把規則交給 parser 或 constrained decoding engine。&lt;/p>
&lt;h2 id="概念位置">概念位置&lt;/h2>
&lt;p>Lark 是 Python 生態的 parsing toolkit，Lark grammar 是它的規則語言。它比傳統 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/bnf/" data-link-title="BNF（Backus-Naur Form）" data-link-desc="用遞迴產生式描述語法的經典記法，是 CFG、parser 與 grammar-constrained sampling 常見的基礎表示">BNF&lt;/a> 更接近實作格式，常見元素包含 rule、terminal、literal、repeat、optional、ignore whitespace 與 start rule。&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">start: query
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">query: FIELD OP VALUE
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">FIELD: &amp;#34;status&amp;#34; | &amp;#34;owner&amp;#34;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl">OP: &amp;#34;=&amp;#34; | &amp;#34;!=&amp;#34;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl">VALUE: ESCAPED_STRING
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl">%import common.ESCAPED_STRING
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">7&lt;/span>&lt;span class="cl">%ignore &amp;#34; &amp;#34;&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>這段規則描述一個很小的查詢語言，只允許固定欄位、固定運算子與 quoted string。&lt;/p>
&lt;h2 id="可觀察訊號與例子">可觀察訊號與例子&lt;/h2>
&lt;p>看到 &lt;code>start:&lt;/code>、大寫 terminal、&lt;code>%import common.*&lt;/code>、&lt;code>%ignore&lt;/code>，通常就是 Lark grammar 或受它影響的格式。LLM 場景常用它描述 JSON 子集、SQL-like query、指令 DSL、分類輸出或固定格式報告。&lt;/p>
&lt;p>Lark grammar 的風險是把 parser 格式誤當跨引擎標準。某些 constrained decoding 工具支援 Lark-like 語法，某些只支援 JSON Schema、regex、GBNF 或自家格式；搬規則前要確認目標 server 能不能解析同一套語法。&lt;/p>
&lt;h2 id="設計責任">設計責任&lt;/h2>
&lt;p>Lark grammar 適合需要清楚描述自訂格式、且工具鏈支援 Lark dialect 的場景。設計時先把合法範圍縮到應用真的需要的語法，再補 validator 處理外部狀態與權限。下一步路由是 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/grammar/" data-link-title="Grammar" data-link-desc="描述合法字串形狀的形式規則，在 structured output 中用來限制 LLM 每一步可輸出的 token">Grammar&lt;/a> 與 &lt;a href="https://tarrragon.github.io/blog/llm/knowledge-cards/dsl/" data-link-title="DSL（Domain-Specific Language）" data-link-desc="為特定業務或技術領域設計的小語言，在 LLM 應用中常作為可解析、可驗證、可執行的中介輸出">DSL&lt;/a>。&lt;/p></description><content:encoded><![CDATA[<p>Lark grammar 的核心概念是「<strong>Lark parser 使用的一種 EBNF-like 語法描述格式</strong>」。在 LLM structured output 文件中看到 lark grammar，通常是在說某個工具用 Lark 風格規則描述合法輸出，再把規則交給 parser 或 constrained decoding engine。</p>
<h2 id="概念位置">概念位置</h2>
<p>Lark 是 Python 生態的 parsing toolkit，Lark grammar 是它的規則語言。它比傳統 <a href="/blog/llm/knowledge-cards/bnf/" data-link-title="BNF（Backus-Naur Form）" data-link-desc="用遞迴產生式描述語法的經典記法，是 CFG、parser 與 grammar-constrained sampling 常見的基礎表示">BNF</a> 更接近實作格式，常見元素包含 rule、terminal、literal、repeat、optional、ignore whitespace 與 start rule。</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">start: query
</span></span><span class="line"><span class="ln">2</span><span class="cl">query: FIELD OP VALUE
</span></span><span class="line"><span class="ln">3</span><span class="cl">FIELD: &#34;status&#34; | &#34;owner&#34;
</span></span><span class="line"><span class="ln">4</span><span class="cl">OP: &#34;=&#34; | &#34;!=&#34;
</span></span><span class="line"><span class="ln">5</span><span class="cl">VALUE: ESCAPED_STRING
</span></span><span class="line"><span class="ln">6</span><span class="cl">%import common.ESCAPED_STRING
</span></span><span class="line"><span class="ln">7</span><span class="cl">%ignore &#34; &#34;</span></span></code></pre></div><p>這段規則描述一個很小的查詢語言，只允許固定欄位、固定運算子與 quoted string。</p>
<h2 id="可觀察訊號與例子">可觀察訊號與例子</h2>
<p>看到 <code>start:</code>、大寫 terminal、<code>%import common.*</code>、<code>%ignore</code>，通常就是 Lark grammar 或受它影響的格式。LLM 場景常用它描述 JSON 子集、SQL-like query、指令 DSL、分類輸出或固定格式報告。</p>
<p>Lark grammar 的風險是把 parser 格式誤當跨引擎標準。某些 constrained decoding 工具支援 Lark-like 語法，某些只支援 JSON Schema、regex、GBNF 或自家格式；搬規則前要確認目標 server 能不能解析同一套語法。</p>
<h2 id="設計責任">設計責任</h2>
<p>Lark grammar 適合需要清楚描述自訂格式、且工具鏈支援 Lark dialect 的場景。設計時先把合法範圍縮到應用真的需要的語法，再補 validator 處理外部狀態與權限。下一步路由是 <a href="/blog/llm/knowledge-cards/grammar/" data-link-title="Grammar" data-link-desc="描述合法字串形狀的形式規則，在 structured output 中用來限制 LLM 每一步可輸出的 token">Grammar</a> 與 <a href="/blog/llm/knowledge-cards/dsl/" data-link-title="DSL（Domain-Specific Language）" data-link-desc="為特定業務或技術領域設計的小語言，在 LLM 應用中常作為可解析、可驗證、可執行的中介輸出">DSL</a>。</p>
]]></content:encoded></item></channel></rss>