diff --git a/src/grammar_cpp.lalrpop b/src/grammar_cpp.lalrpop index 067f6a2..fa7aa6a 100644 --- a/src/grammar_cpp.lalrpop +++ b/src/grammar_cpp.lalrpop @@ -27,6 +27,7 @@ extern { "flag master" => Token::FlagMaster, "flag econ" => Token::FlagEcon, "flag game" => Token::FlagGame, + "flag colalpha" => Token::FlagColAlpha, "string lit" => Token::StringLiteral(), "ident" => Token::Identifier(), @@ -35,6 +36,7 @@ extern { ")" => Token::RParen, "," => Token::Comma, "|" => Token::Pipe, + ";" => Token::Semicolon, "MaxClients" => Token::MaxClients, "ServerInfoLevelMin" => Token::ServerInfoLevelMin, "ServerInfoLevelMax" => Token::ServerInfoLevelMax, @@ -54,6 +56,7 @@ Flag: CFGFlags = { "flag master" => CFGFlags::MASTER, "flag econ" => CFGFlags::ECON, "flag game" => CFGFlags::GAME, + "flag colalpha" => CFGFlags::COLALPHA, } Flags: CFGFlags = { @@ -81,7 +84,7 @@ Int: i64 = { Entry: ConfigEntry = { "config int" "(" "," "," "," "," "," - "," ")" => { + "," ")" ";"? => { ConfigEntry { description: desc, @@ -98,7 +101,7 @@ Entry: ConfigEntry = { }, "config str" "(" "," "," "," "," - "," ")" => { + "," ")" ";"? => { ConfigEntry { description: desc, @@ -114,7 +117,7 @@ Entry: ConfigEntry = { }, "config col" "(" "," "," "," - "," ")" => { + "," ")" ";"? => { ConfigEntry { description: desc, flags, diff --git a/src/lib.rs b/src/lib.rs index 64ff29b..4b13e06 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -15,6 +15,7 @@ bitflags! { const MASTER = 0b00100000; const ECON = 0b01000000; const GAME = 0b10000000; + const COLALPHA = 0b100000000; } } @@ -60,14 +61,18 @@ mod tests { #[test] fn parses() { let header_file = include_str!("../config_variables.h"); + dbg!("before"); let lexer = Lexer::new(header_file); + dbg!("after"); let parser = grammar_cpp::ConfigsParser::new(); + dbg!("after 2"); match parser.parse(lexer) { Ok(entries) => { dbg!(&entries); } Err(e) => { + dbg!(&e); let x: ParseError = e; match x { ParseError::InvalidToken { location } => todo!(), @@ -75,14 +80,16 @@ mod tests { ParseError::UnrecognizedToken { token, expected } => { dbg!("unrecognized token"); dbg!(&token); - dbg!(header_file.slice(token.0 - 20..token.2 + 20)); + dbg!(header_file.slice(token.0..token.2)); dbg!(expected); } ParseError::ExtraToken { token } => todo!(), ParseError::User { error } => { match error { - LexicalError::InvalidToken(_, r) => { - dbg!("invalid token"); + LexicalError::InvalidToken(a, r) => { + dbg!("user invalid token"); + dbg!(a); + dbg!(&r); println!("{:?}", header_file.slice(r).unwrap()) } }; diff --git a/src/tokens_cpp.rs b/src/tokens_cpp.rs index 004fb49..85269f8 100644 --- a/src/tokens_cpp.rs +++ b/src/tokens_cpp.rs @@ -1,13 +1,13 @@ -use logos::{Logos, SpannedIter}; +use logos::{FilterResult, Logos, SpannedIter}; use std::{convert::Infallible, fmt, ops::Range}; // to implement the Display trait #[derive(Logos, Clone, Debug, PartialEq)] #[logos( error = LexingError, skip r"[ \t\n\f]+", - skip r"/\*.*\*/" // why doesnt this skip? - skip r"#.*\n?", - skip r"//.*\n?",)] + skip r"#[^\n]*\n?", + skip r"//[^\n]*\n?", +)] pub enum Token { #[token("MACRO_CONFIG_INT")] MacroConfigInt, @@ -32,12 +32,17 @@ pub enum Token { FlagEcon, #[token("CFGFLAG_GAME")] FlagGame, + #[token("CFGFLAG_COLALPHA")] + FlagColAlpha, - #[regex(r#""(?:[^"]|\\")*""#, |lex| lex.slice().parse().ok())] + #[regex(r#""(?:[^"]|\\")*""#, |lex| { + let slice = lex.slice(); + slice[1..(slice.len()-1)].to_string() + })] StringLiteral(String), - #[regex(r"[_a-zA-Z][_0-9a-zA-Z]+", |lex| lex.slice().parse().ok())] + #[regex(r"[_a-zA-Z][_0-9a-zA-Z]+", |lex| lex.slice().to_string())] Identifier(String), - #[regex(r"-?[0-9][_0-9]*", |lex| lex.slice().parse().ok())] + #[regex(r"-?[0-9][_0-9]*", |lex| lex.slice().parse())] Integer(i64), #[token("(")] @@ -48,6 +53,8 @@ pub enum Token { Comma, #[token("|")] Pipe, + #[token(";")] + Semicolon, #[token("MAX_CLIENTS")] MaxClients, @@ -55,6 +62,14 @@ pub enum Token { ServerInfoLevelMin, #[token("SERVERINFO_LEVEL_MAX")] ServerInfoLevelMax, + + #[token("/*", |lex| { + let len = lex.remainder().find("*/").unwrap(); + lex.bump(len + 2); // include len of `*/` + + FilterResult::Skip::<(), Infallible> + })] + BlockComment, } impl fmt::Display for Token {