1
0
Fork 0
forked from AbleOS/ableos

Added struct declarations to parsers

This commit is contained in:
Talha Qamar 2024-09-11 01:17:36 +05:00
parent 0594b99a59
commit 94b7aabdec
3 changed files with 164 additions and 26 deletions

View file

@ -1,19 +1,30 @@
pub mod protocol;
mod parser;
use std::io::Read;
use self::parser::parse;
use {
logos::{Lexer, Logos},
protocol::Protocol,
};
#[derive(Logos, Debug, PartialEq, Clone)]
#[logos(skip r"[ \t\n\f]+")] // Ignore this regex pattern between tokens
enum Token {
#[regex("//[^\n]*\n", logos::skip)]
Ignored,
// Tokens can be literal strings, of any length.
#[token("protocol")]
Protocol,
#[token("enum")]
Enum,
#[token("struct")]
Struct,
#[token("{")]
LBrace,
@ -41,7 +52,7 @@ enum Token {
RArrow,
#[regex("[a-zA-Z_]+", |lex|{lex.slice().to_string()})]
Text(String),
Identifier(String),
#[regex("[1234567890]+", |lex|{lex.slice().parse::<u64>().unwrap()})]
Number(u64),
@ -66,13 +77,11 @@ pub fn build_idl(name: String) {
Err(err) => println!("{:?}", err),
}
}
build(tokens);
println!("{:?}", parse(tokens));
}
fn build(a: Vec<Token>) {
for toke in a {
println!("{:?}", toke);
}
}
fn open_protocol(name: String) -> String {

128
dev/src/idl/parser.rs Normal file
View file

@ -0,0 +1,128 @@
use std::{iter::Peekable, slice::Iter};
use super::Token;
#[derive(Debug, Clone, PartialEq)]
pub struct AST(Vec<DecoratedDeclaration>);
#[derive(Debug, Clone, PartialEq)]
struct DecoratedDeclaration(Option<Decorator>, Declaration);
#[derive(Debug, Clone, PartialEq)]
struct Decorator(String);
#[derive(Debug, Clone, PartialEq)]
enum Declaration{
EnumDeclaration,
StructDeclaration(StructDeclaration),
ProtocolDeclaration,
}
#[derive(Debug, Clone, PartialEq)]
struct StructDeclaration {
name : String,
members : Vec<StructMember>,
}
#[derive(Debug, Clone, PartialEq)]
struct StructMember {
name : String,
type_name : String,
}
fn parse_decorated_declarations(tokens : &mut Peekable<Iter<'_, Token>>) -> Vec<DecoratedDeclaration>{
let mut declarations : Vec<DecoratedDeclaration> = Vec::new();
loop {
match tokens.peek() {
Some(_) => {
let decoration = parse_decoration(tokens);
let declaration = parse_declaration(tokens);
declarations.push(DecoratedDeclaration(decoration, declaration));
},
None => break,
}
}
return declarations
}
fn parse_decoration(tokens : &mut Peekable<Iter<'_, Token>>) -> Option<Decorator> {
match tokens.peek().unwrap() {
Token::Decorator(s) => {
tokens.next();
Some(Decorator(s.to_string()))
},
Token::DecoratorOption(s) => {
tokens.next();
Some(Decorator(s.to_string()))
},
_ => None,
}
}
fn parse_declaration(tokens : &mut Peekable<Iter<'_, Token>>) -> Declaration {
match tokens.next().expect("Expected a statement, got end of tokens") {
Token::Enum => {
Declaration::EnumDeclaration
},
Token::Struct => {
Declaration::StructDeclaration(parse_struct_declaration(tokens))
},
Token::Protocol => {
Declaration::ProtocolDeclaration
},
_ => panic!("Expected a enumeration, struct or protocol")
}
}
fn parse_struct_declaration(tokens : &mut Peekable<Iter<'_, Token>>) -> StructDeclaration{
if let Token::Identifier(identifier) = tokens.next().unwrap() {
let mut members : Vec<StructMember> = Vec::new();
assert!(tokens.next().expect("expected a {{, got end of token list") == &Token::LBrace, "expected a {{ after identifier in struct declaration");
loop {
match tokens.peek().expect("expected }} or struct members") {
&Token::RBrace => break,
_ => {
// if we're in this branch then there MUST a struct member here
members.push(parse_struct_member(tokens));
// is there a comma here?
// nightmare
if **(tokens.peek().unwrap()) == Token::Comma {
// consume comma
tokens.next();
}
// if there isn't a comma nor a right brace after the struct member
else if **(tokens.peek().unwrap()) != Token::RBrace {
panic!("expected a comma to separate struct members");
}
}
}
}
tokens.next(); // consume closing bracket
return StructDeclaration{
name : identifier.to_string(),
members,
}
}
else {
panic!("Expected an identifier after 'struct'")
}
}
fn parse_struct_member(tokens : &mut Peekable<Iter<'_, Token>>) -> StructMember {
if let Token::Identifier(name) = tokens.next().unwrap(){
assert!(tokens.next().unwrap() == &Token::Colon, "expected colon after struct member name");
if let Token::Identifier(type_name) = tokens.next().unwrap(){
StructMember{name: name.to_string(), type_name: type_name.to_string()}
}
else{
panic!("Expected type name in Struct Member");
}
}
else {
panic!("Expected identifier in Struct Member");
}
}
pub fn parse(tokens : Vec<Token>) -> AST{
let mut tokens_iter = tokens.iter().peekable();
AST(parse_decorated_declarations(&mut tokens_iter))
}

View file

@ -1,24 +1,25 @@
@auto_increment
enum LogLevel {
Error = 0,
Warn,
Info,
Debug,
Trace,
}
@auto_increment
enum LogResult {
Err = 0,
Ok,
}
// A comment
//@auto_increment
//enum LogLevel {
// Error = 0,
// Warn,
// Info,
// Debug,
// Trace,
//}
//
//@auto_increment
//enum LogResult {
// Err = 0,
// Ok,
//}
@example
struct Log {
log_level: LogLevel,
}
@visibility(public)
protocol Log {
fn log(Log) -> LogResult;
fn flush() -> LogResult;
}
//@visibility(public)
//protocol Log {
// fn log(Log) -> LogResult;
// fn flush() -> LogResult;
//}