Skip to content

[WIP] move syntax parser to LALR #12

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 10 commits into
base: main
Choose a base branch
from
Draft
62 changes: 62 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ categories = ["parser-implementations", "compilers"]

[dependencies]
rusty_parser = "1.1.0"
rusty_lr = "3.3.1"
252 changes: 90 additions & 162 deletions src/ast/declarator.rs
Original file line number Diff line number Diff line change
@@ -1,211 +1,139 @@
use super::expression::Expression;
use super::typename::TypeInfo;

use std::vec::Vec;

#[derive(Debug, Clone)]
pub enum Declarator {
Identifier(DeclIdentifier),
DirectArrayFixed(DeclDirectArrayFixed),
DirectArrayUnbounded(DeclDirectArrayUnbounded),
DirectFunction(DeclDirectFunction),
Const(DeclConst),
Pointer(DeclPointer),
Init(DeclInit),
AbstractArrayFixed(DeclAbstractArrayFixed),
AbstractArrayUnbounded(DeclAbstractArrayUnbounded),
AbstractFunction(DeclAbstractFunction),
AbstractPointer(DeclAbstractPointer),
AbstractConst(DeclAbstractConst),
}

impl Declarator {
pub fn resolve_typeinfo(&self, info: TypeInfo) -> (Option<String>, TypeInfo) {
match self {
Declarator::Identifier(decl) => decl.resolve_typeinfo(info),
Declarator::DirectArrayFixed(decl) => decl.resolve_typeinfo(info),
Declarator::DirectArrayUnbounded(decl) => decl.resolve_typeinfo(info),
Declarator::DirectFunction(decl) => decl.resolve_typeinfo(info),
Declarator::Const(decl) => decl.resolve_typeinfo(info),
Declarator::Pointer(decl) => decl.resolve_typeinfo(info),
Declarator::Init(decl) => decl.resolve_typeinfo(info),
Declarator::AbstractArrayFixed(decl) => decl.resolve_typeinfo(info),
Declarator::AbstractArrayUnbounded(decl) => decl.resolve_typeinfo(info),
Declarator::AbstractFunction(decl) => decl.resolve_typeinfo(info),
Declarator::AbstractPointer(decl) => decl.resolve_typeinfo(info),
Declarator::AbstractConst(decl) => decl.resolve_typeinfo(info),
}
}
pub enum StorageClassSpecifier {
Static,
Typedef,
Extern,
Auto,
Register,
}

#[derive(Debug, Clone)]
pub struct DeclIdentifier {
pub name: String,
pub enum TypeQualifier {
Const,
Volatile,
}
impl DeclIdentifier {
pub fn resolve_typeinfo(&self, info: TypeInfo) -> (Option<String>, TypeInfo) {
(Some(self.name.clone()), info)
}
#[derive(Debug, Clone)]
pub enum TypeSpecifier {
Void,
Char,
Short,
Int,
Long,
Float,
Double,
Signed,
Unsigned,
Typename(String),
StructOrUnion(StructOrUnionSpecifier),
Enum(EnumSpecifier),
}

#[derive(Debug, Clone)]
pub struct DeclDirectArrayFixed {
pub declarator: Box<Declarator>,
pub size: Expression,
}
impl DeclDirectArrayFixed {
pub fn resolve_typeinfo(&self, info: TypeInfo) -> (Option<String>, TypeInfo) {
let (name, info) = self.declarator.resolve_typeinfo(info);
let size = self
.size
.get_constant_i64()
.expect("Array size must be constant") as usize;
(name, TypeInfo::Array(Box::new(info), Some(size)))
}
pub struct StructOrUnionSpecifier {
pub is_struct: bool,
pub name: Option<String>,
pub decls: Option<Vec<StructDeclaration>>,
}

#[derive(Debug, Clone)]
pub struct DeclDirectArrayUnbounded {
pub declarator: Box<Declarator>,
pub struct StructDeclaration {
pub specs: Vec<SpecifierQualifier>,
pub declarators: Vec<Declarator>,
}
impl DeclDirectArrayUnbounded {
pub fn resolve_typeinfo(&self, info: TypeInfo) -> (Option<String>, TypeInfo) {
let (name, info) = self.declarator.resolve_typeinfo(info);
(name, TypeInfo::Array(Box::new(info), None))
}

#[derive(Debug, Clone)]
pub struct EnumSpecifier {
pub name: Option<String>,
pub enumerators: Option<Vec<Enumerator>>,
}

#[derive(Debug, Clone)]
pub struct DeclDirectFunction {
pub declarator: Box<Declarator>,
pub params: Vec<(Option<String>, TypeInfo)>,
pub struct Enumerator {
pub name: String,
pub value: Option<Expression>,
}
impl DeclDirectFunction {
pub fn resolve_typeinfo(&self, info: TypeInfo) -> (Option<String>, TypeInfo) {
let (name, return_type) = self.declarator.resolve_typeinfo(info);
let mut params = Vec::new();
for (_, param_type) in &self.params {
params.push(param_type.clone());
}
(name, TypeInfo::Function(Box::new(return_type), params))
}

#[derive(Debug, Clone)]
pub enum DeclarationSpecifier {
StorageClassSpecifier(StorageClassSpecifier),
TypeQualifier(TypeQualifier),
TypeSpecifier(TypeSpecifier),
}

#[derive(Debug, Clone)]
pub struct DeclConst {
pub declarator: Box<Declarator>,
pub enum SpecifierQualifier {
TypeQualifier(TypeQualifier),
TypeSpecifier(TypeSpecifier),
}
impl DeclConst {
pub fn resolve_typeinfo(&self, info: TypeInfo) -> (Option<String>, TypeInfo) {
let (name, info) = self.declarator.resolve_typeinfo(info);
(name, TypeInfo::Const(Box::new(info)))
}

#[derive(Debug, Clone)]
pub struct Typename {
pub specs: Vec<SpecifierQualifier>,
pub declarator: Option<Box<Declarator>>,
}

#[derive(Debug, Clone)]
pub struct DeclPointer {
pub declarator: Box<Declarator>,
pub struct ParameterDeclaration {
pub specs: Vec<DeclarationSpecifier>,
pub declarator: Option<Box<Declarator>>,
}
impl DeclPointer {
pub fn resolve_typeinfo(&self, info: TypeInfo) -> (Option<String>, TypeInfo) {
let (name, info) = self.declarator.resolve_typeinfo(info);
(name, TypeInfo::Pointer(Box::new(info)))
}
#[derive(Debug, Clone)]
pub struct ParameterList {
pub params: Vec<ParameterDeclaration>,
pub variadic: bool,
}

#[derive(Debug, Clone)]
pub struct DeclInit {
pub declarator: Box<Declarator>,
pub initializer: Option<Expression>,
pub enum Declarator {
Identifier(DeclIdentifier),
Const(DeclConst),
Pointer(DeclPointer),
Volatile(DeclVolatile),
ArrayFixed(DeclArrayFixed),
ArrayUnbounded(DeclArrayUnbounded),
Function(DeclFunction),
}
impl DeclInit {
pub fn resolve_typeinfo(&self, info: TypeInfo) -> (Option<String>, TypeInfo) {
self.declarator.resolve_typeinfo(info)
}

#[derive(Debug, Clone)]
pub struct DeclIdentifier {
pub name: String,
}

#[derive(Debug, Clone)]
pub struct DeclAbstractArrayFixed {
pub struct DeclConst {
pub declarator: Option<Box<Declarator>>,
pub size: Expression,
}
impl DeclAbstractArrayFixed {
pub fn resolve_typeinfo(&self, info: TypeInfo) -> (Option<String>, TypeInfo) {
let (name, info_) = if let Some(decl) = &self.declarator {
decl.resolve_typeinfo(info)
} else {
(None, info)
};
let size = self
.size
.get_constant_i64()
.expect("Array size must be constant") as usize;
(name, TypeInfo::Array(Box::new(info_), Some(size)))
}
}

#[derive(Debug, Clone)]
pub struct DeclAbstractArrayUnbounded {
pub struct DeclPointer {
pub declarator: Option<Box<Declarator>>,
}
#[derive(Debug, Clone)]
pub struct DeclVolatile {
pub declarator: Option<Box<Declarator>>,
}
impl DeclAbstractArrayUnbounded {
pub fn resolve_typeinfo(&self, info: TypeInfo) -> (Option<String>, TypeInfo) {
let (name, info_) = if let Some(decl) = &self.declarator {
decl.resolve_typeinfo(info)
} else {
(None, info)
};
(name, TypeInfo::Array(Box::new(info_), None))
}
#[derive(Debug, Clone)]
pub struct DeclInit {
pub declarator: Box<Declarator>,
pub initializer: Option<Expression>,
}

#[derive(Debug, Clone)]
pub struct DeclAbstractFunction {
pub declarator: Option<Box<Declarator>>,
pub params: Vec<(Option<String>, TypeInfo)>,
}
impl DeclAbstractFunction {
pub fn resolve_typeinfo(&self, info: TypeInfo) -> (Option<String>, TypeInfo) {
let (name, return_type) = if let Some(decl) = &self.declarator {
decl.resolve_typeinfo(info)
} else {
(None, info)
};
(
name,
TypeInfo::Function(
Box::new(return_type),
self.params.iter().map(|(_, t)| t.clone()).collect(),
),
)
}
}

#[derive(Debug, Clone)]
pub struct DeclAbstractPointer {
pub struct DeclArrayFixed {
pub declarator: Option<Box<Declarator>>,
}
impl DeclAbstractPointer {
pub fn resolve_typeinfo(&self, info: TypeInfo) -> (Option<String>, TypeInfo) {
let (name, info_) = if let Some(decl) = &self.declarator {
decl.resolve_typeinfo(info)
} else {
(None, info)
};
(name, TypeInfo::Pointer(Box::new(info_)))
}
pub size: Expression,
}

#[derive(Debug, Clone)]
pub struct DeclAbstractConst {
pub struct DeclArrayUnbounded {
pub declarator: Option<Box<Declarator>>,
}
impl DeclAbstractConst {
pub fn resolve_typeinfo(&self, info: TypeInfo) -> (Option<String>, TypeInfo) {
let (name, info_) = if let Some(decl) = &self.declarator {
decl.resolve_typeinfo(info)
} else {
(None, info)
};
(name, TypeInfo::Const(Box::new(info_)))
}

#[derive(Debug, Clone)]
pub struct DeclFunction {
pub declarator: Option<Box<Declarator>>,
pub params: ParameterList,
}
Loading