diff --git a/tools/codegen/src/ast/raw/mod.rs b/tools/codegen/src/ast/raw/mod.rs index 6b97274..d0165f2 100644 --- a/tools/codegen/src/ast/raw/mod.rs +++ b/tools/codegen/src/ast/raw/mod.rs @@ -6,11 +6,24 @@ mod utils; #[derive(Debug, Default, Property)] pub(crate) struct Ast { + syntax_version: Option, namespace: String, imports: Vec, decls: Vec, } +impl Default for SyntaxVersionStmt { + fn default() -> Self { + Self { major: 1, minor: 0 } + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Property)] +pub(crate) struct SyntaxVersionStmt { + major: usize, + minor: usize, +} + #[derive(Debug, Clone, Property)] pub(crate) struct ImportStmt { name: String, diff --git a/tools/codegen/src/ast/raw/utils.rs b/tools/codegen/src/ast/raw/utils.rs index e27735e..e5b14e1 100644 --- a/tools/codegen/src/ast/raw/utils.rs +++ b/tools/codegen/src/ast/raw/utils.rs @@ -3,6 +3,7 @@ use std::{ffi, fs, io::Read as _, path::Path, str::FromStr}; use pest::{error::Error as PestError, iterators::Pairs, Parser as _}; use same_file::is_same_file; +use crate::ast::raw::SyntaxVersionStmt; use crate::{ ast::raw as ast, parser, @@ -184,6 +185,23 @@ impl parser::Parser { panic!("grammar should have only one EOI"); } match pair.as_rule() { + parser::Rule::syntax_version_stmt => { + let mut pair = pair.into_inner(); + let syntax_version = SyntaxVersionStmt { + major: pair.next_usize(), + minor: pair.next_usize(), + }; + pair.next_should_be_none(); + if ast.syntax_version.is_some() { + // compare ast.syntax_version and syntax_version + // panic if there is a conflict syntax_version + if ast.syntax_version != Some(syntax_version) { + panic!("all schema files' syntax version should be same"); + } + } else { + ast.syntax_version = Some(syntax_version); + } + } parser::Rule::import_stmt => { let mut pair = pair.into_inner(); let node = pair.next_import(path, imported_depth); @@ -265,6 +283,10 @@ impl parser::Parser { if !eoi { panic!("grammar should have only one EOI"); } + + if ast.syntax_version.is_none() { + ast.syntax_version = Some(SyntaxVersionStmt::default()); + } Ok(()) } } diff --git a/tools/codegen/src/grammar.pest b/tools/codegen/src/grammar.pest index 15c073b..4e1ef3b 100644 --- a/tools/codegen/src/grammar.pest +++ b/tools/codegen/src/grammar.pest @@ -78,8 +78,14 @@ path_super = @{ "../" } path = { path_super* ~ (identifier ~ "/")* ~ identifier } import_stmt = { "import" ~ (brk)+ ~ path ~ (brk)* ~ stmt_end } +syntax_major_version = @{ digit* } +syntax_minor_version = @{ digit* } +syntax_version = _{ syntax_major_version ~ "." ~ syntax_minor_version } +syntax_version_stmt = { "syntax" ~ (brk)* ~ "=" ~ (brk)* ~ syntax_version ~ (brk)* ~ stmt_end} + grammar = { SOI ~ (brk)* ~ + (syntax_version_stmt)? ~ (brk)* ~ (import_stmt ~ (brk)*)* ~ decl_stmt ~ ((brk)* ~ decl_stmt)* ~ (brk)* ~