This commit is contained in:
Edgar 2023-07-06 12:10:34 +02:00
parent 6018e8e4b2
commit 1e5fc5beb0
No known key found for this signature in database
GPG key ID: 70ADAE8F35904387
3 changed files with 38 additions and 13 deletions

View file

@ -27,6 +27,7 @@ extern {
"flag master" => Token::FlagMaster, "flag master" => Token::FlagMaster,
"flag econ" => Token::FlagEcon, "flag econ" => Token::FlagEcon,
"flag game" => Token::FlagGame, "flag game" => Token::FlagGame,
"flag colalpha" => Token::FlagColAlpha,
"string lit" => Token::StringLiteral(<String>), "string lit" => Token::StringLiteral(<String>),
"ident" => Token::Identifier(<String>), "ident" => Token::Identifier(<String>),
@ -35,6 +36,7 @@ extern {
")" => Token::RParen, ")" => Token::RParen,
"," => Token::Comma, "," => Token::Comma,
"|" => Token::Pipe, "|" => Token::Pipe,
";" => Token::Semicolon,
"MaxClients" => Token::MaxClients, "MaxClients" => Token::MaxClients,
"ServerInfoLevelMin" => Token::ServerInfoLevelMin, "ServerInfoLevelMin" => Token::ServerInfoLevelMin,
"ServerInfoLevelMax" => Token::ServerInfoLevelMax, "ServerInfoLevelMax" => Token::ServerInfoLevelMax,
@ -54,6 +56,7 @@ Flag: CFGFlags = {
"flag master" => CFGFlags::MASTER, "flag master" => CFGFlags::MASTER,
"flag econ" => CFGFlags::ECON, "flag econ" => CFGFlags::ECON,
"flag game" => CFGFlags::GAME, "flag game" => CFGFlags::GAME,
"flag colalpha" => CFGFlags::COLALPHA,
} }
Flags: CFGFlags = { Flags: CFGFlags = {
@ -81,7 +84,7 @@ Int: i64 = {
Entry: ConfigEntry = { Entry: ConfigEntry = {
"config int" "(" <sym:"ident"> "," <name:"ident"> "," "config int" "(" <sym:"ident"> "," <name:"ident"> ","
<def:Int> "," <min:Int> "," <max:Int> "," <def:Int> "," <min:Int> "," <max:Int> ","
<flags:Flags> "," <desc:"string lit"> ")" => { <flags:Flags> "," <desc:"string lit"> ")" ";"? => {
ConfigEntry { ConfigEntry {
description: desc, description: desc,
@ -98,7 +101,7 @@ Entry: ConfigEntry = {
}, },
"config str" "(" <sym:"ident"> "," <name:"ident"> "," "config str" "(" <sym:"ident"> "," <name:"ident"> ","
<max_length:Int> "," <default:"string lit"> "," <max_length:Int> "," <default:"string lit"> ","
<flags:Flags> "," <desc:"string lit"> ")" => { <flags:Flags> "," <desc:"string lit"> ")" ";"? => {
ConfigEntry { ConfigEntry {
description: desc, description: desc,
@ -114,7 +117,7 @@ Entry: ConfigEntry = {
}, },
"config col" "(" <sym:"ident"> "," <name:"ident"> "," "config col" "(" <sym:"ident"> "," <name:"ident"> ","
<default:Int> "," <default:Int> ","
<flags:Flags> "," <desc:"string lit"> ")" => { <flags:Flags> "," <desc:"string lit"> ")" ";"? => {
ConfigEntry { ConfigEntry {
description: desc, description: desc,
flags, flags,

View file

@ -15,6 +15,7 @@ bitflags! {
const MASTER = 0b00100000; const MASTER = 0b00100000;
const ECON = 0b01000000; const ECON = 0b01000000;
const GAME = 0b10000000; const GAME = 0b10000000;
const COLALPHA = 0b100000000;
} }
} }
@ -60,14 +61,18 @@ mod tests {
#[test] #[test]
fn parses() { fn parses() {
let header_file = include_str!("../config_variables.h"); let header_file = include_str!("../config_variables.h");
dbg!("before");
let lexer = Lexer::new(header_file); let lexer = Lexer::new(header_file);
dbg!("after");
let parser = grammar_cpp::ConfigsParser::new(); let parser = grammar_cpp::ConfigsParser::new();
dbg!("after 2");
match parser.parse(lexer) { match parser.parse(lexer) {
Ok(entries) => { Ok(entries) => {
dbg!(&entries); dbg!(&entries);
} }
Err(e) => { Err(e) => {
dbg!(&e);
let x: ParseError<usize, Token, LexicalError> = e; let x: ParseError<usize, Token, LexicalError> = e;
match x { match x {
ParseError::InvalidToken { location } => todo!(), ParseError::InvalidToken { location } => todo!(),
@ -75,14 +80,16 @@ mod tests {
ParseError::UnrecognizedToken { token, expected } => { ParseError::UnrecognizedToken { token, expected } => {
dbg!("unrecognized token"); dbg!("unrecognized token");
dbg!(&token); dbg!(&token);
dbg!(header_file.slice(token.0 - 20..token.2 + 20)); dbg!(header_file.slice(token.0..token.2));
dbg!(expected); dbg!(expected);
} }
ParseError::ExtraToken { token } => todo!(), ParseError::ExtraToken { token } => todo!(),
ParseError::User { error } => { ParseError::User { error } => {
match error { match error {
LexicalError::InvalidToken(_, r) => { LexicalError::InvalidToken(a, r) => {
dbg!("invalid token"); dbg!("user invalid token");
dbg!(a);
dbg!(&r);
println!("{:?}", header_file.slice(r).unwrap()) println!("{:?}", header_file.slice(r).unwrap())
} }
}; };

View file

@ -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 use std::{convert::Infallible, fmt, ops::Range}; // to implement the Display trait
#[derive(Logos, Clone, Debug, PartialEq)] #[derive(Logos, Clone, Debug, PartialEq)]
#[logos( #[logos(
error = LexingError, error = LexingError,
skip r"[ \t\n\f]+", skip r"[ \t\n\f]+",
skip r"/\*.*\*/" // why doesnt this skip? skip r"#[^\n]*\n?",
skip r"#.*\n?", skip r"//[^\n]*\n?",
skip r"//.*\n?",)] )]
pub enum Token { pub enum Token {
#[token("MACRO_CONFIG_INT")] #[token("MACRO_CONFIG_INT")]
MacroConfigInt, MacroConfigInt,
@ -32,12 +32,17 @@ pub enum Token {
FlagEcon, FlagEcon,
#[token("CFGFLAG_GAME")] #[token("CFGFLAG_GAME")]
FlagGame, 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), 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), 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), Integer(i64),
#[token("(")] #[token("(")]
@ -48,6 +53,8 @@ pub enum Token {
Comma, Comma,
#[token("|")] #[token("|")]
Pipe, Pipe,
#[token(";")]
Semicolon,
#[token("MAX_CLIENTS")] #[token("MAX_CLIENTS")]
MaxClients, MaxClients,
@ -55,6 +62,14 @@ pub enum Token {
ServerInfoLevelMin, ServerInfoLevelMin,
#[token("SERVERINFO_LEVEL_MAX")] #[token("SERVERINFO_LEVEL_MAX")]
ServerInfoLevelMax, 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 { impl fmt::Display for Token {