برنامه نویسی

ایجاد لکسر ساده و سریع با آرم

سلام بچه ها ، این اولین پست من است. من در حال نوشتن این پست هستم که علت آن را که واقعاً دوست داشتم و از آن لذت بردم در هنگام نوشتن Tokenizer با آرم ها ، اما نمی توانستم آنچه را که می خواستم ، شاید آن را خیلی نفهمیدم اما آرم ها بسیار خوب و زیبا هستند و این دقیقاً مانند Flex است.

آرم ها چیست؟ آرم ها سریع و آسان برای استفاده از ژنراتور Lexer نوشته شده در Rust است ، بنابراین اگر می خواهید یک عمل ساده لکسینگ را در Rust انجام دهید می توانید آرم ها را انتخاب کنید ، می توانید Lexer مبتنی بر Token را با آن تهیه کنید ، همچنین در این نمونه ما یک لکسر ساده مبتنی بر Token ایجاد خواهیم کرد.

بیایید با ایجاد یک پروژه ساده شروع کنیم:

شرح تصویر

cargo new my_lexer
cd my_lexer
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

اکنون باید وابستگی آرم را به پروژه خود اضافه کنیم:

شرح تصویر

cargo add logos
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

خوب ، اکنون ما آماده شروع کار هستیم ، من با ایجاد یک فایل نمونه شروع می کنم ، می خواهم یک زنگ بسیار ساده مانند نحو را نشان دهم ، بیایید یک پرونده my_example.txt را ایجاد کنیم.

// examples/my_example.txt
fn main() {
   print("hello")
}
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

اکنون باید مسیر پرونده را در برنامه Rust خود طی کنیم ، می توانیم از طریق استفاده از ARG ها به آن برسیم و همچنین باید پرونده گرفته شده را بخوانیم.

// src/main.rs
use std::env;
use std::fs::read_to_string;

fn main() {
    let args: Vec<String> = env::args().collect();
    if args.len() >= 2 {
        let file = &args[1];
        let ctx = read_to_string(file).expect("Should have been able to read the file");
        println!("{:?}", ctx);
    } else {
        eprintln!("pls give me a text file.");
    }
}
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

خوب ، بنابراین اکنون ما یک برنامه خواننده فایل ساده داریم. حال بیایید چند نشانه ایجاد کنیم.

#[derive(Logos, Debug, PartialEq)]
#[logos(skip r"[ \t\n\f]+")]
pub enum Token<'a> {
    #[token("fn")]
    Function,
    #[token("{")]
    LeftCurlyBracet,
    #[token("}")]
    RightCurlyBracet,
    #[token("(")]
    LeftBracet,
    #[token(")")]
        RightBracet,

    #[regex(r"[a-zA-Z][a-zA-Z0-9]*")]
    Text(&'a str),
    #[regex(r#""([^"\\]|\\.)*""#, priority = 1)]
    String(&'a str),
}
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

ما در اینجا چه کاری انجام دادیم؟ در مرحله اول ، ما آرم های مشتق ، فرار از مکان های سفید ، Newline ، EOF و Tab را تنظیم می کنیم ، پس از مشتق ها ، ما فقط یک رمز ساده با نشانه های خود با نشانه های مشتق ایجاد کردیم.
ما داریم:

  • نشانه های استاتیک: fn ، (،) ، {،}
  • متن و رشته.

و در آخر می توانیم ورودی را از بین ببریم:

// src/main.rs
use std::env;
use std::fs::read_to_string;
use logos::Logos;

#[derive(Logos, Debug, PartialEq)]
#[logos(skip r"[ \t\n\f]+")]
pub enum Token<'a> {
    #[token("fn")]
    Function,
    #[token("{")]
    LeftCurlyBracet,
    #[token("}")]
    RightCurlyBracet,
    #[token("(")]
    LeftBracet,
    #[token(")")]
        RightBracket,

    #[regex(r"[a-zA-Z][a-zA-Z0-9]*")]
    Text(&'a str),
    #[regex(r#""([^"\\]|\\.)*""#, priority = 1)]
    String(&'a str),
}

fn main() {
    let args: Vec<String> = env::args().collect();
    if args.len() >= 2 {
        let file = &args[1];
        let ctx = read_to_string(file).expect("Should have been able to read the file");
        for res in Token::lexer(&ctx) {
            match res {
                Ok(token) => println!("{:#?}", token),
                Err(e) => panic!("some error occurred {:?}", e)
            }
        }
    } else {
        eprintln!("pls give me a text file.");
    }
}
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

✨result✨

شرح تصویر

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا