NOM เป็นห้องสมุด combinators parser ที่เขียนด้วย Rust เป้าหมายคือการจัดหาเครื่องมือในการสร้างตัวแยกวิเคราะห์ที่ปลอดภัยโดยไม่ลดทอนความเร็วหรือการใช้หน่วยความจำ ด้วยเหตุนี้จึงใช้ การพิมพ์ และ ความปลอดภัยของหน่วยความจำ ที่แข็งแกร่งของ Rust อย่างกว้างขวางในการสร้างตัวแยกวิเคราะห์ที่รวดเร็วและถูกต้องและให้ฟังก์ชั่นมาโครและลักษณะที่เป็นนามธรรมของข้อผิดพลาดส่วนใหญ่
NOM จะนำไบต์ออกจากไฟล์ของคุณอย่างมีความสุข :)
ตัวแยกวิเคราะห์สีหกเหลี่ยม:
use nom :: {
bytes :: complete :: { tag , take_while_m_n } ,
combinator :: map_res ,
sequence :: Tuple ,
IResult ,
Parser ,
} ;
# [ derive ( Debug , PartialEq ) ]
pub struct Color {
pub red : u8 ,
pub green : u8 ,
pub blue : u8 ,
}
fn from_hex ( input : & str ) -> Result < u8 , std :: num :: ParseIntError > {
u8 :: from_str_radix ( input , 16 )
}
fn is_hex_digit ( c : char ) -> bool {
c . is_digit ( 16 )
}
fn hex_primary ( input : & str ) -> IResult < & str , u8 > {
map_res (
take_while_m_n ( 2 , 2 , is_hex_digit ) ,
from_hex
) . parse ( input )
}
fn hex_color ( input : & str ) -> IResult < & str , Color > {
let ( input , _ ) = tag ( "#" ) ( input ) ? ;
let ( input , ( red , green , blue ) ) = ( hex_primary , hex_primary , hex_primary ) . parse ( input ) ? ;
Ok ( ( input , Color { red , green , blue } ) )
}
fn main ( ) {
println ! ( "{:?}" , hex_color ( "#2F14DF" ) )
}
# [ test ]
fn parse_color ( ) {
assert_eq ! (
hex_color ( "#2F14DF" ) ,
Ok ( (
"" ,
Color {
red: 47 ,
green: 20 ,
blue: 223 ,
}
) )
) ;
}
หากคุณต้องการความช่วยเหลือในการพัฒนาตัวแยกวิเคราะห์ของคุณโปรด ping geal
บน IRC (Libera, geeknode, OFTC) ไปที่ #nom-parsers
บน Libera IRC หรือในห้องแชทของ Gitter
หากคุณต้องการเขียน:
NOM ได้รับการออกแบบมาเพื่อแยกรูปแบบไบนารีอย่างถูกต้องตั้งแต่ต้น เมื่อเทียบกับตัวแยกวิเคราะห์ C ที่เขียนด้วยลายมือตามปกติ Parsers NOM นั้นเร็วพอ ๆ กับช่องโหว่บัฟเฟอร์ล้นและจัดการกับรูปแบบทั่วไปสำหรับคุณ:
ตัวอย่างโครงการ:
ในขณะที่ NOM ถูกสร้างขึ้นสำหรับรูปแบบไบนารีในตอนแรกมันก็เริ่มทำงานได้ดีเช่นกันกับรูปแบบข้อความ จากรูปแบบตามบรรทัดเช่น CSV ไปจนถึงรูปแบบที่ซับซ้อนและซ้อนกันมากขึ้นเช่น JSON, NOM สามารถจัดการได้และให้เครื่องมือที่มีประโยชน์แก่คุณ:
ตัวอย่างโครงการ:
ในขณะที่ตัวแยกวิเคราะห์ภาษาการเขียนโปรแกรมมักจะเขียนด้วยตนเองเพื่อความยืดหยุ่นและประสิทธิภาพมากขึ้น NOM สามารถ (และประสบความสำเร็จ) ใช้เป็นตัวแยกวิเคราะห์ต้นแบบสำหรับภาษา
NOM จะเริ่มต้นได้อย่างรวดเร็วด้วยประเภทข้อผิดพลาดที่กำหนดเองที่ทรงพลังซึ่งคุณสามารถใช้ประโยชน์จาก NOM_Locate เพื่อระบุบรรทัดที่แน่นอนและคอลัมน์ของข้อผิดพลาด ไม่จำเป็นต้องแยกเฟส Tokenizing, Lexing และ Parsing: NOM สามารถจัดการการแยกวิเคราะห์ช่องว่างโดยอัตโนมัติและสร้าง AST ในสถานที่
ตัวอย่างโครงการ:
ในขณะที่รูปแบบจำนวนมาก (และรหัสที่จัดการ) สมมติว่าพวกเขาสามารถพอดีกับข้อมูลที่สมบูรณ์ในหน่วยความจำมีรูปแบบที่เราได้รับส่วนหนึ่งของข้อมูลในครั้งเดียวเช่นรูปแบบเครือข่ายหรือไฟล์ขนาดใหญ่ NOM ได้รับการออกแบบมาสำหรับพฤติกรรมที่ถูกต้องด้วยข้อมูลบางส่วน: หากมีข้อมูลไม่เพียงพอที่จะตัดสินใจ NOM จะบอกคุณว่าต้องการมากขึ้นแทนที่จะส่งคืนผลลัพธ์ที่ไม่ถูกต้องอย่างเงียบ ๆ ไม่ว่าข้อมูลของคุณจะมาทั้งหมดหรือเป็นชิ้นผลลัพธ์ควรเหมือนกัน
ช่วยให้คุณสร้างเครื่องจักรสถานะที่ทรงพลังและกำหนดได้สำหรับโปรโตคอลของคุณ
ตัวอย่างโครงการ:
Parser Combinators เป็นวิธีการแยกวิเคราะห์ที่แตกต่างจากซอฟต์แวร์เช่น Lex และ YACC แทนที่จะเขียนไวยากรณ์ในไฟล์แยกต่างหากและสร้างรหัสที่เกี่ยวข้องคุณใช้ฟังก์ชั่นขนาดเล็กมากโดยมีจุดประสงค์เฉพาะเช่น "ใช้ 5 ไบต์" หรือ "จดจำคำว่า 'http'" และรวบรวมในรูปแบบที่มีความหมายเช่น " รับรู้ 'http' จากนั้นเป็นพื้นที่แล้วเป็นเวอร์ชัน " รหัสผลลัพธ์มีขนาดเล็กและดูเหมือนว่าไวยากรณ์ที่คุณจะเขียนด้วยวิธีการแยกวิเคราะห์อื่น ๆ
สิ่งนี้มีข้อดีเล็กน้อย:
Parsers Nom มีไว้สำหรับ:
&[u8]
และ parsers จะทำงานให้มากที่สุดเท่าที่จะทำได้ในชิ้นอาร์เรย์ไบต์ (แต่ไม่ จำกัด เฉพาะพวกเขา) มาตรฐานบางอย่างมีอยู่ใน GitHub
NOM 7.0 ซีรี่ส์รองรับ RustC เวอร์ชัน 1.56 หรือมากกว่า
นโยบายปัจจุบันคือสิ่งนี้จะได้รับการอัปเดตในรุ่น NOM ที่สำคัญต่อไปเท่านั้น
NOM มีอยู่ใน Crates.io และสามารถรวมอยู่ในโครงการที่เปิดใช้งานสินค้าของคุณเช่นนี้:
[ dependencies ]
nom = " 7 "
มีคุณสมบัติการรวบรวมบางอย่าง:
alloc
: (เปิดใช้งานโดยค่าเริ่มต้น) หากปิดใช้งาน NOM สามารถทำงานใน no_std
สร้างโดยไม่ต้องจัดสรรหน่วยความจำ หากเปิดใช้งาน combinators ที่จัดสรร (เช่น many0
) จะพร้อมใช้งานstd
: (เปิดใช้งานโดยค่าเริ่มต้นเปิดใช้งาน alloc
ด้วย) หากปิดการใช้งาน NOM สามารถทำงานในการสร้าง no_std
คุณสามารถกำหนดค่าคุณสมบัติเหล่านั้นเช่นนี้:
[ dependencies . nom ]
version = " 7 "
default-features = false
features = [ " alloc " ]
นี่คือรายการ (ไม่ครบถ้วนสมบูรณ์) ของโครงการที่รู้จักโดยใช้ NOM:
ต้องการสร้างตัวแยกวิเคราะห์ใหม่โดยใช้ nom
? รายการรูปแบบที่ยังไม่ได้ใช้งานยังมีอยู่ที่นี่
ต้องการเพิ่มตัวแยกวิเคราะห์ของคุณที่นี่หรือไม่? สร้างคำขอดึง!
NOM เป็นผลไม้ของการทำงานของผู้มีส่วนร่วมหลายคนในช่วงหลายปีที่ผ่านมาขอบคุณมากสำหรับความช่วยเหลือของคุณ!