network_simulator/
lib.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT license.
3
4//======================================================================================================================
5// Modules
6//======================================================================================================================
7
8pub mod glue;
9
10//======================================================================================================================
11// Imports
12//======================================================================================================================
13
14use anyhow::Result;
15use glue::Event;
16use lrlex::{DefaultLexerTypes, LRNonStreamingLexer, LRNonStreamingLexerDef, LexerDef};
17use lrpar::{LexError, LexParseError, Lexeme, Lexer, NonStreamingLexer};
18
19lrlex::lrlex_mod!("tokens.l");
20lrpar::lrpar_mod!("grammar.y");
21
22//======================================================================================================================
23// Standalone Functions
24//======================================================================================================================
25pub fn run_lexer(line: &str, verbose: bool) -> Result<()> {
26    let lexerdef: LRNonStreamingLexerDef<DefaultLexerTypes> = tokens_l::lexerdef();
27    let lexer: LRNonStreamingLexer<'_, '_, DefaultLexerTypes> = lexerdef.lexer(line);
28    for lexeme in lexer.iter() {
29        match lexeme {
30            // Succeeded to match a known lexeme.
31            Ok(lexeme) => {
32                if verbose {
33                    let text: &str = lexer.span_str(lexeme.span());
34                    let id: u32 = lexeme.tok_id();
35                    let name: &str = lexerdef
36                        .get_rule_by_id(id)
37                        .name
38                        .as_ref()
39                        .expect("lexical rules should have names");
40                    println!("Lexeme: name={:?}, text={:?}", name, text);
41                }
42            },
43            // Failed match a known lexeme.
44            Err(e) => {
45                let start: usize = e.span().start();
46                let end: usize = e.span().end();
47                let token: &str = &line[start..end];
48                let cause: String = format!("Unknown Lexeme (start={:?}, end={:?}, token={:?})", start, end, token);
49                eprintln!("Lexical Error: {:?}", cause);
50                anyhow::bail!(cause);
51            },
52        }
53    }
54
55    Ok(())
56}
57
58pub fn run_parser(line: &str, verbose: bool) -> Result<Option<Event>> {
59    let lexerdef: LRNonStreamingLexerDef<DefaultLexerTypes> = tokens_l::lexerdef();
60    let lexer: LRNonStreamingLexer<'_, '_, DefaultLexerTypes> = lexerdef.lexer(&line);
61    let (result, errs): (_, Vec<LexParseError<u32, DefaultLexerTypes>>) = grammar_y::parse(&lexer);
62    if !errs.is_empty() {
63        for e in errs {
64            let cause: String = format!("{:?}", e.pp(&lexer, &grammar_y::token_epp));
65            println!("Syntax Error: {:?}", cause);
66            anyhow::bail!(cause)
67        }
68    }
69
70    if verbose {
71        println!("Syntax Analysis: passed");
72    }
73
74    Ok(result.unwrap())
75}