亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

rust 中的 EBNF簡介舉例

 更新時間:2025年05月12日 14:33:11   作者:Uncomfortableskiy  
這篇文章主要介紹了rust 中的 EBNF簡介舉例,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧

在 rust 參考手冊中,有大量類似:

句法
MacroInvocation :
	SimplePath ! DelimTokenTree
DelimTokenTree :
	  ( TokenTree* )
	| [ TokenTree* ]
	| { TokenTree* }
TokenTree :
	   Token排除 定界符(delimiters) | DelimTokenTree
MacroInvocationSemi :
	  SimplePath ! ( TokenTree* ) ;
	| SimplePath ! [ TokenTree* ] ;
	| SimplePath ! { TokenTree* }

這樣抽象的玩意兒(宏 - Rust 參考手冊)。這種閱讀體驗(yàn)差的要死的東西,一看就是學(xué)術(shù)界搞出來的東西,這篇文章就是講這種東西應(yīng)該怎么讀。

1. 什么是 EBNF?

在計(jì)算機(jī)科學(xué)中,當(dāng)我們描述一種語言(比如編程語言、數(shù)據(jù)格式或配置文件)的結(jié)構(gòu)時,需要一種精確、無歧義的方式。擴(kuò)展巴科斯范式 (Extended Backus-Naur Form, EBNF) 就是這樣一種元語言(描述其他語言的語言)標(biāo)記法。它通過一系列嚴(yán)格定義的規(guī)則,清晰地表達(dá)一種語言的語法。

EBNF 源自并擴(kuò)展了巴科斯范式 (Backus-Naur Form, BNF)。BNF 最初由約翰·巴科斯 (John Backus) 和彼得·諾爾 (Peter Naur) 為描述 ALGOL 60 編程語言的語法而設(shè)計(jì)。EBNF 在 BNF 的基礎(chǔ)上增加了一些方便的符號,使得語法描述更為簡潔和易讀。

2. 核心概念

在學(xué)習(xí) EBNF 之前,我們需要了解幾個基本概念:

  • **規(guī)則 (Rule / Production):**EBNF 的核心是規(guī)則。每條規(guī)則定義了一個特定的語法結(jié)構(gòu)是如何由更小的部分組成的。**非終結(jié)符 (Non-terminal Symbol):**代表一個語法概念或一個可以被進(jìn)一步分解的結(jié)構(gòu)。它通常是其他規(guī)則的名稱,表示“這里可以放置一個符合某某規(guī)則定義的結(jié)構(gòu)”。
  • 在 EBNF 中,非終結(jié)符通常用描述性的名稱表示,例如表達(dá)式, 語句, 數(shù)字。在一些傳統(tǒng) BNF 中,非終結(jié)符會被尖括號 < > 包圍,如 <expression>,但在現(xiàn)代 EBNF 中,直接使用名稱更為常見。
  • **終結(jié)符 (Terminal Symbol):**代表語言中最小的、不可再分的詞法單元或字面值。它們是語法結(jié)構(gòu)最終落實(shí)到的具體字符或字符串。例如,編程語言中的關(guān)鍵字 (if, while)、操作符 (+, -, *, /)、數(shù)字字面量 (123, 3.14)、字符串字面量 ("hello") 等都是終結(jié)符。在 EBNF 中,終結(jié)符通常用引號 "' 包圍,或者直接寫出(如果不會引起歧義)。

3. EBNF 語法符號詳解

EBNF 通過一些特殊符號來組織規(guī)則、非終結(jié)符和終結(jié)符:

  • ::==(定義為):
    • 這是規(guī)則定義的核心操作符,讀作“被定義為”或“由…組成”。它將左側(cè)的非終結(jié)符(要定義的結(jié)構(gòu))與右側(cè)的該結(jié)構(gòu)的具體構(gòu)成聯(lián)系起來。
    • 示例:數(shù)字 ::= "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
    • 這條規(guī)則定義了“數(shù)字”可以是什么。
  • |(或 / 選擇):
    • 豎線表示“或者”,用于在規(guī)則定義的右側(cè)提供多個可能的選擇。被 | 分隔的各項(xiàng)是互斥的選項(xiàng)。
    • 示例:布爾值 ::= "true" | "false" “布爾值”可以是 “true” 或者 “false”。
  • 并列(順序連接):
    • 當(dāng)規(guī)則定義的右側(cè)有多個符號(終結(jié)符或非終結(jié)符)依次排列時,它們表示這些部分必須按照給定的順序出現(xiàn)。
    • 示例:賦值語句 ::= 標(biāo)識符 "=" 表達(dá)式 一條“賦值語句”由一個“標(biāo)識符”,后跟一個等號終結(jié)符,再后跟一個“表達(dá)式”組成。
  • ()(分組):

圓括號用于將一組符號括起來,形成一個邏輯單元。這使得可以將重復(fù)、可選等操作符應(yīng)用于整個組。

示例:函數(shù)調(diào)用 ::= 函數(shù)名 "(" (參數(shù)列表)? ")" 這里 (參數(shù)列表)? 被括號括起來,表示可選的參數(shù)列表部分。

  • ?(可選 / 零次或一次):
    • 問號表示其緊鄰的前一個符號或分組是可選的,即可以出現(xiàn)零次或一次。
    • 示例:整數(shù) ::= ("+" | "-")? 數(shù)字序列 一個“整數(shù)”可以有一個可選的正負(fù)號,后面跟著一個“數(shù)字序列”。
  • *(重復(fù)零次或多次):
  • 星號表示其緊鄰的前一個符號或分組可以出現(xiàn)零次、一次或多次。
  • 示例:標(biāo)識符 ::= 字母 (字母 | 數(shù)字)* 一個“標(biāo)識符”由一個“字母”開頭,后面可以跟零個或多個“字母”或“數(shù)字”。
  • +(重復(fù)一次或多次):
    • 加號表示其緊鄰的前一個符號或分組必須至少出現(xiàn)一次,也可以出現(xiàn)多次。
    • 示例:數(shù)字序列 ::= 數(shù)字+ 一個“數(shù)字序列”由至少一個“數(shù)字”組成。
  • [...](可選分組 - 另一種常見表示):
    • 一些 EBNF 變體使用方括號 [] 來表示一個可選的部分,等同于 (...)?。
    • 示例:參數(shù)列表 ::= "[" 參數(shù) ("," 參數(shù))* "]" (這里假設(shè) [] 是可選參數(shù)列表的定界符) 或者:整數(shù) ::= ["+" | "-"] 數(shù)字序列 (等同于上面的 ("+" | "-")?)
  • {...}(重復(fù)分組 - 另一種常見表示):
    • 一些 EBNF 變體使用花括號 {} 來表示一個可以重復(fù)零次或多次的部分,等同于 (...)*。
    • 示例:注釋 ::= "/*" {任意字符} "*/" 一個“注釋”由 /* 開始,中間可以有零個或多個“任意字符”,并以 */ 結(jié)束。
  • 終結(jié)符的表示:
    • 如前所述,終結(jié)符通常用引號包圍,例如 "if", '+'。
    • 如果終結(jié)符本身就是一個不會引起歧義的字符序列(例如不包含 EBNF 特殊符號),有時也可以直接寫出。
  • 注釋:
    • 不同的 EBNF 工具或規(guī)范可能有不同的注釋方式,常見的有 (* 這是一個注釋 *) 或類似 C 語言的 //。本教程主要關(guān)注語法規(guī)則本身。

4. 如何閱讀 EBNF 規(guī)則

  • 找到規(guī)則定義: 每條規(guī)則通常以一個非終結(jié)符開始,后跟 ::==
  • 從左到右分析: 閱讀定義右側(cè)的符號序列。
  • 理解選擇: 遇到 | 時,知道這代表多個選項(xiàng)中的一個。
  • 注意順序: 并列的符號表示它們必須按順序出現(xiàn)。
  • 識別重復(fù)和可選: 留意 *, +, ? (或 [], {}) 的含義。
  • 處理分組: () (以及有時 []{}) 會將一部分符號視為一個整體。
  • 遞歸: 規(guī)則的右側(cè)可以包含規(guī)則本身或其他非終結(jié)符,這種遞歸是定義復(fù)雜結(jié)構(gòu)(如嵌套表達(dá)式)的關(guān)鍵。
  • 區(qū)分終結(jié)符與非終結(jié)符: 終結(jié)符是語言的“原子”,非終結(jié)符是需要進(jìn)一步展開的“概念”。

5. 示例

讓我們看一些使用 EBNF 定義的例子:

示例 1:簡單的電子郵件地址

EBNF

郵箱地址 ::= 用戶名 "@" 域名
用戶名   ::= 字符+
域名     ::= (子域名 ".")*頂級域名
子域名   ::= 字符+
頂級域名 ::= 字符+
字符     ::= 字母 | 數(shù)字 | "_" | "-"
字母     ::= "a" | ... | "z" | "A" | ... | "Z" // 省略所有字母
數(shù)字     ::= "0" | ... | "9"             // 省略所有數(shù)字
  • 這個例子定義了“郵箱地址”的結(jié)構(gòu)。
  • 用戶名字符 用了 + 表示至少一個。
  • 域名 中的 (子域名 ".")* 表示可以有零個或多個由點(diǎn)分隔的子域名。

示例 2:算術(shù)表達(dá)式(簡化版)

EBNF

表達(dá)式 ::= 項(xiàng) (("+" | "-") 項(xiàng))*
項(xiàng)     ::= 因子 (("*" | "/") 因子)*
因子   ::= 數(shù)字 | "(" 表達(dá)式 ")"
數(shù)字   ::= ("0"|"1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9")+
  • 這個例子展示了如何定義包含運(yùn)算符優(yōu)先級和括號的算術(shù)表達(dá)式。
  • 表達(dá)式項(xiàng) 的定義是遞歸的(因子中包含 表達(dá)式),這允許嵌套。
  • (("+" | "-") 項(xiàng))* 表示可以有零個或多個由加號或減號連接的“項(xiàng)”。

示例 3:一個簡單列表結(jié)構(gòu)

EBNF

列表 ::= "[" [元素 ("," 元素)*] "]"
元素 ::= 標(biāo)識符 | 數(shù)字
標(biāo)識符 ::= 字母 (字母 | 數(shù)字)*
// 字母和數(shù)字的定義同上
  • 列表由方括號包圍。
  • [元素 ("," 元素)*] 表示方括號內(nèi)的內(nèi)容是可選的(因?yàn)檎麄€被 [] 包裹,這里 [] 是 EBNF 的可選符號,而非列表的定界符——為了清晰,我們也可以寫成 (元素 ("," 元素)*)?)。
  • 如果列表非空,則至少有一個“元素”,后續(xù)可以有零個或多個由逗號分隔的“元素”。

6. 優(yōu)點(diǎn)與局限

  • 優(yōu)點(diǎn):
    • 精確性: 能夠無歧義地描述復(fù)雜的語法結(jié)構(gòu)。
    • 可讀性: 相較于其他形式化方法,EBNF 相對容易閱讀和理解(尤其是帶有擴(kuò)展符號時)。
    • 標(biāo)準(zhǔn)化: 雖然存在一些變體,但核心概念是共通的。
    • 工具支持: 有許多工具(如解析器生成器 ANTLR, YACC/Bison)可以直接使用 EBNF 或類似的語法定義來自動生成解析代碼。
  • 局限:
    • 上下文無關(guān): EBNF 主要描述上下文無關(guān)文法。它通常不直接處理那些依賴于上下文的語義規(guī)則(例如,變量必須先聲明后使用,類型匹配等)。這些通常需要額外的語義分析來處理。
    • 歧義性: 盡管目標(biāo)是無歧義,但仍可能寫出有歧義的 EBNF 規(guī)則(即一個輸入串可以有多種解析方式)。消除歧義有時需要重寫規(guī)則或依賴解析器的特定策略(如運(yùn)算符優(yōu)先級和結(jié)合性聲明)。
    • 冗余和復(fù)雜性: 一旦里面定義的內(nèi)容多了,難讀得要死。

到此這篇關(guān)于rust 中的 EBNF 介紹的文章就介紹到這了,更多相關(guān)rust 中的 EBNF 介紹內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Rust for循環(huán)語法糖背后的API場景分析

    Rust for循環(huán)語法糖背后的API場景分析

    for語句是一種能確定循環(huán)次數(shù)的循環(huán),for 語句用于執(zhí)行代碼塊指定的次數(shù),今天通過本文給大家介紹Rust for循環(huán)語法糖背后的API場景分析,感興趣的朋友跟隨小編一起看看吧
    2022-11-11
  • Rust使用csv crate構(gòu)建CSV文件讀取器的全過程

    Rust使用csv crate構(gòu)建CSV文件讀取器的全過程

    這篇文章主要學(xué)習(xí)如何基于Rust使用csv這個crate構(gòu)建一個CSV文件讀取器的過程,學(xué)習(xí)了csv相關(guān)的用法以及一些往期學(xué)過的crate的復(fù)習(xí),兼顧了實(shí)用性和Rust的學(xué)習(xí),需要的朋友可以參考下
    2024-05-05
  • 使用cargo install安裝Rust二進(jìn)制工具過程

    使用cargo install安裝Rust二進(jìn)制工具過程

    cargoinstall是一個用于安裝包含可執(zhí)行目標(biāo)的Rust包的命令行工具,類似于系統(tǒng)軟件包管理器,但它為Rust開發(fā)者提供了一種簡潔的方式來安裝和管理命令行工具,安裝后,二進(jìn)制文件會存儲在$HOME/.cargo/bin目錄中,需要將該目錄添加到$PATH環(huán)境變量中才能在命令行中直接運(yùn)行
    2025-02-02
  • Rust中不可變變量與const的區(qū)別詳解

    Rust中不可變變量與const的區(qū)別詳解

    Rust作者認(rèn)為變量默認(rèn)應(yīng)該是immutable,即聲明后不能被改變的變量,這一點(diǎn)是讓跨語言學(xué)習(xí)者覺得很別扭,不過這一點(diǎn)小的改變帶來了諸多好處,本節(jié)我們來學(xué)習(xí)Rust中不可變變量與const的區(qū)別,需要的朋友可以參考下
    2024-02-02
  • Rust使用Sqlx連接Mysql的實(shí)現(xiàn)

    Rust使用Sqlx連接Mysql的實(shí)現(xiàn)

    數(shù)據(jù)庫在編程中是一個很重要的環(huán)節(jié),本文主要介紹了Rust使用Sqlx連接Mysql的實(shí)現(xiàn),記錄rust如何操作數(shù)據(jù)庫并以mysql為主的做簡單的使用說明,感興趣的可以了解一下
    2024-03-03
  • Rust標(biāo)量類型的具體使用

    Rust標(biāo)量類型的具體使用

    本文主要介紹了Rust標(biāo)量類型的具體使用,其中包括整數(shù)類型、浮點(diǎn)類型、布爾類型以及字符類型,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-03-03
  • rust生命周期詳解

    rust生命周期詳解

    生命周期是rust中用來規(guī)定引用的有效作用域,在大多數(shù)時候,無需手動聲明,因?yàn)榫幾g器能夠自動推導(dǎo),這篇文章主要介紹了rust生命周期相關(guān)知識,需要的朋友可以參考下
    2023-03-03
  • Rust語言從入門到精通之Tokio的Channel深入理解

    Rust語言從入門到精通之Tokio的Channel深入理解

    這篇文章主要為大家介紹了Rust語言從入門到精通之Tokio的Channel深入理解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-05-05
  • 詳解Rust中的方法

    詳解Rust中的方法

    方法其實(shí)就是結(jié)構(gòu)體的成員函數(shù),在C語言中的結(jié)構(gòu)體是沒有成員函數(shù)的,但是Rust畢竟也是一門面向?qū)ο蟮木幊陶Z言,所以給結(jié)構(gòu)體加上方法的特性很符合面向?qū)ο蟮奶攸c(diǎn),這篇文章主要介紹了Rust中的方法,需要的朋友可以參考下
    2022-10-10
  • Rust的slab庫使用場景分析

    Rust的slab庫使用場景分析

    slab 是一個輕量級、高性能的工具,非常適合管理固定大小的資源集合,尤其是在網(wǎng)絡(luò)編程和事件驅(qū)動架構(gòu)中,這篇文章主要介紹了Rust的slab庫使用教程,需要的朋友可以參考下
    2024-12-12

最新評論