From c1cb1a89f99bcf74fcc07b483bcca5b51b498783 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=9F=B3=E5=8D=9A=E6=96=87?= Date: Thu, 14 Nov 2024 23:40:25 +0800 Subject: [PATCH] support parser whole file --- lib/src/backend/lua/test.rs | 5 ++++- lib/src/parser/default_impl/mod.rs | 8 ++++++++ lib/src/parser/lalrpop_impl/mod.rs | 18 ++++++++++++++++-- lib/src/parser/lalrpop_impl/st.lalrpop | 9 +++++++-- lib/src/parser/mod.rs | 14 +++++++++++++- lib/src/serde/xml.rs | 5 ++++- lib/src/test/mod.rs | 9 ++++++--- lib/src/test/test_file.rs | 2 +- lsp/src/lsp.rs | 11 ++++++++++- 9 files changed, 69 insertions(+), 12 deletions(-) diff --git a/lib/src/backend/lua/test.rs b/lib/src/backend/lua/test.rs index 51a44a1..5057e85 100644 --- a/lib/src/backend/lua/test.rs +++ b/lib/src/backend/lua/test.rs @@ -9,7 +9,10 @@ fn generate_module, S2: AsRef>(decl: S1, body: S2, writer: & let mgr = UnitsManager::new(); let ctx = ModuleContext::new(ModuleKind::Application); let mut lexer = StLexerBuilder::new().build_str(decl.as_ref()); - let decl = ParserBuilder::default().build().parse(&mut lexer).unwrap(); + let decl = ParserBuilder::default() + .build() + .parse_decl(&mut lexer) + .unwrap(); let fun_id = ctx.write().add_declaration(decl, Uuid::nil()); let mut lexer = StLexerBuilder::new().build_str(body.as_ref()); diff --git a/lib/src/parser/default_impl/mod.rs b/lib/src/parser/default_impl/mod.rs index af0af16..fbfddcb 100644 --- a/lib/src/parser/default_impl/mod.rs +++ b/lib/src/parser/default_impl/mod.rs @@ -26,6 +26,14 @@ impl DefaultParser { } impl ParserTrait for DefaultParser { + fn name(&self) -> String { + "DefaultParser".to_string() + } + + fn parse_pou(&self, lexer: &mut StLexer) -> Result<(Declaration, Statement), ParseError> { + todo!() + } + #[inline] fn parse_decl(&self, lexer: &mut StLexer) -> Result { DefaultParserImpl::new(lexer.into_iter()).parse_declaration() diff --git a/lib/src/parser/lalrpop_impl/mod.rs b/lib/src/parser/lalrpop_impl/mod.rs index 9f64499..283b3c5 100644 --- a/lib/src/parser/lalrpop_impl/mod.rs +++ b/lib/src/parser/lalrpop_impl/mod.rs @@ -38,7 +38,8 @@ where pub struct LalrpopParser { decl_parser: Lazy, - body_parser: Lazy, + body_parser: Lazy, + pou_parser: Lazy, literal_parser: Lazy, expression_parser: Lazy, } @@ -53,7 +54,8 @@ impl Default for LalrpopParser { fn default() -> Self { Self { decl_parser: Lazy::new(st::DeclarationParser::new), - body_parser: Lazy::new(st::StFunctionParser::new), + body_parser: Lazy::new(st::StBodyParser::new), + pou_parser: Lazy::new(st::StPOUParser::new), literal_parser: Lazy::new(st::LiteralExprParser::new), expression_parser: Lazy::new(st::ExprParser::new), } @@ -61,6 +63,18 @@ impl Default for LalrpopParser { } impl ParserTrait for LalrpopParser { + #[inline] + fn name(&self) -> String { + "Lalrpop Parser".to_string() + } + + #[inline] + fn parse_pou(&self, lexer: &mut StLexer) -> Result<(Declaration, Statement), ParseError> { + self.pou_parser + .parse(LalrPopLexerWrapper::new(lexer.into_iter())) + .map_err(Into::into) + } + #[inline] fn parse_decl(&self, lexer: &mut StLexer) -> Result { self.decl_parser diff --git a/lib/src/parser/lalrpop_impl/st.lalrpop b/lib/src/parser/lalrpop_impl/st.lalrpop index 49cbe61..6acd36f 100644 --- a/lib/src/parser/lalrpop_impl/st.lalrpop +++ b/lib/src/parser/lalrpop_impl/st.lalrpop @@ -107,8 +107,13 @@ SmallComma3: SmallVec3 = { } }; -/// Top-level ST function -pub StFunction = StatementList; +/// Top-Level ST decl + impl body +pub StPOU: (Declaration, Statement) = { + Declaration StatementList => (<>), +} + +/// Top-level ST function body +pub StBody = StatementList; /// ST Statements StatementList: Statement = { diff --git a/lib/src/parser/mod.rs b/lib/src/parser/mod.rs index ecabe4b..147136a 100644 --- a/lib/src/parser/mod.rs +++ b/lib/src/parser/mod.rs @@ -74,7 +74,17 @@ pub struct Parser { impl Parser { #[inline] - pub fn parse(&self, lexer: &mut StLexer) -> Result { + pub fn name(&self) -> String { + self.inner.name() + } + + #[inline] + pub fn parse_pou(&self, lexer: &mut StLexer) -> Result<(Declaration, Statement), ParseError> { + self.inner.parse_pou(lexer) + } + + #[inline] + pub fn parse_decl(&self, lexer: &mut StLexer) -> Result { self.inner.parse_decl(lexer) } @@ -118,6 +128,8 @@ impl ParserBuilder { } pub trait ParserTrait { + fn name(&self) -> String; + fn parse_pou(&self, lexer: &mut StLexer) -> Result<(Declaration, Statement), ParseError>; fn parse_decl(&self, lexer: &mut StLexer) -> Result; fn parse_stmt(&self, lexer: &mut StLexer) -> Result; fn parse_literal(&self, lexer: &mut StLexer) -> Result; diff --git a/lib/src/serde/xml.rs b/lib/src/serde/xml.rs index 942da3f..03c21f2 100644 --- a/lib/src/serde/xml.rs +++ b/lib/src/serde/xml.rs @@ -39,7 +39,10 @@ impl From for ModuleContext { for pou in proj.pou_list.pou { let mut lexer = StLexerBuilder::new().build_str(&pou.interface.content); - let decl = ParserBuilder::default().build().parse(&mut lexer).unwrap(); + let decl = ParserBuilder::default() + .build() + .parse_decl(&mut lexer) + .unwrap(); let func = ctx_write.add_declaration( decl, pou.uuid_text diff --git a/lib/src/test/mod.rs b/lib/src/test/mod.rs index 54616fe..c6bb69e 100644 --- a/lib/src/test/mod.rs +++ b/lib/src/test/mod.rs @@ -13,7 +13,7 @@ fn test_decl_parse() { let code = fs::read_to_string(&f).unwrap(); let mut lexer = StLexerBuilder::new().build_str(&code); - match parser.parse(&mut lexer) { + match parser.parse_decl(&mut lexer) { Ok(_) => assert!(lexer.eof(), "{}", f.display()), Err(e) => panic!("{}: {:?}", f.display(), e), } @@ -60,14 +60,17 @@ fn test_scope_lookup() { let app_ctx = mgr.write().get_context(app_id).unwrap(); let mut global = StLexerBuilder::new().build_str("VAR_GLOBAL END_VAR VAR_GLOBAL g1: REAL; END_VAR"); - let global = ParserBuilder::default().build().parse(&mut global).unwrap(); + let global = ParserBuilder::default() + .build() + .parse_decl(&mut global) + .unwrap(); let _global_id = app_ctx.write().add_declaration(global, Uuid::nil()); let mut test_func = StLexerBuilder::new().build_str("program prg: int VAR g1: BYTE; END_VAR end_program"); let test_fun_decl = ParserBuilder::default() .build() - .parse(&mut test_func) + .parse_decl(&mut test_func) .unwrap(); let test_fun_decl_id = app_ctx.write().add_declaration(test_fun_decl, Uuid::nil()); diff --git a/lib/src/test/test_file.rs b/lib/src/test/test_file.rs index 43e2c2d..df960f5 100644 --- a/lib/src/test/test_file.rs +++ b/lib/src/test/test_file.rs @@ -7,7 +7,7 @@ fn main() { let mut lexer = StLexerBuilder::new().build_file(f).unwrap(); let parser = ParserBuilder::default().build(); - match parser.parse(&mut lexer) { + match parser.parse_decl(&mut lexer) { Ok(r) => { println!("{:?}", r); } diff --git a/lsp/src/lsp.rs b/lsp/src/lsp.rs index 9909416..7cba435 100644 --- a/lsp/src/lsp.rs +++ b/lsp/src/lsp.rs @@ -2,7 +2,7 @@ use crate::lsp_types::{TokenModifiers, TokenTypes}; use dashmap::DashMap; use ropey::Rope; use serde_json::Value; -use stc::parser::{StLexerBuilder, TokenKind}; +use stc::parser::{ParserBuilder, StLexerBuilder, TokenKind}; use stc::prelude::UnitsManager; use strum::IntoEnumIterator; use tower_lsp::jsonrpc::Result; @@ -50,6 +50,15 @@ impl StcLsp { pub fn on_file_change(&self, url: &Url, text: String) { let rope = text.into(); self.src_mgr.insert(url.clone(), rope); + + let rope_data = self.src_mgr.get(url).unwrap(); + let code = rope_data.value(); + + let mut lexer = StLexerBuilder::default().build_iter(code.chars()); + let parser = ParserBuilder::default().build(); + + let (_decl, _body) = parser.parse_pou(&mut lexer).unwrap(); + // TODO: save parse results } }