simple_c_lexer/
simple_c_lexer.rs1use codespan_reporting::diagnostic::*;
2use orecc_front::{chars, Codebase, TokenReader};
3
4pub fn main() {
5 let args = std::env::args().collect::<Vec<_>>();
6 if args.len() != 2 {
7 eprintln!("Usage: cargo run --example simple_c_lexer -- sample.c");
8 return;
9 }
10
11 let code = std::fs::read_to_string(&args[1]).unwrap();
12 let mut codebase = Codebase::new();
13 let key = codebase.add(args[1].clone(), code);
14
15 let mut reader = TokenReader::new(codebase.get(key).unwrap().source().clone());
16 while let Some(char) = reader.next_char() {
17 if chars::is_digit(char) {
18 println!("Number {}", reader.next_token(chars::is_digit, char));
20 } else if chars::is_ident_start(char) {
21 println!(
23 "Ident {}",
24 reader.next_token(chars::is_ident_continue, char)
25 );
26 } else if char == '"' {
27 let mut string = String::new();
29 loop {
30 match reader.next_char() {
31 Some('\\') => match reader.next_char() {
33 Some('n') => string.push('\n'),
34 Some(char) => string.push(char),
35 None => codebase.emit( Diagnostic::error()
37 .with_message("expected escape code")
38 .with_labels(vec![Label::primary(
39 key,
40 reader.cursor..reader.cursor + 1,
41 )
42 .with_message("here")]),
43 ),
44 },
45
46 Some('"') => break,
48
49 Some(char) if char != '\n' => string.push(char),
51 _ => {
52 codebase.emit(
53 Diagnostic::error()
54 .with_message("unterminated string")
55 .with_labels(vec![Label::primary(
56 key,
57 reader.cursor..reader.cursor + 1,
58 )
59 .with_message("here")]),
60 );
61 break;
62 }
63 }
64 }
65 println!("String {:?}", string);
66 } else if ['(', ')', '{', '}', ';'].contains(&char) {
67 println!("Operator {}", char);
69 }
70 }
71}