jvm_assembler/formats/jasm/parser/
mod.rs

1//! JASM 语法分析器
2//!
3//! 这个模块实现了 JASM 汇编语言的语法分析器,将 token 流转换为抽象语法树 (AST)。
4
5use crate::formats::jasm::{ast::*, lexer::JasmTokenType};
6use gaia_types::{
7    helpers::Url,
8    reader::{SourcePosition, Token, TokenStream},
9    GaiaError, Result, SourceLocation,
10};
11
12/// JASM 语法分析器
13#[derive(Debug)]
14pub struct JasmParser {
15    /// 源文件 URL(可选)
16    url: Option<Url>,
17}
18
19impl JasmParser {
20    /// 创建新的 JASM 解析器
21    pub fn new(url: Option<Url>) -> Self {
22        Self { url }
23    }
24
25    /// 解析 token 流为 JASM AST
26    ///
27    /// # 参数
28    /// * `tokens` - 要解析的 token 流
29    ///
30    /// # 返回值
31    /// 返回解析后的 `JasmRoot` AST 或错误
32    pub fn parse(&self, tokens: TokenStream<JasmTokenType>) -> Result<JasmRoot> {
33        let mut parser_state = ParserState::new(self.url.clone(), tokens.raw, tokens.tokens.into_inner());
34
35        parser_state.parse_root()
36    }
37}
38
39/// 解析器内部状态
40struct ParserState<'input> {
41    /// 源文件 URL
42    url: Option<Url>,
43    /// 源代码
44    source: &'input str,
45    /// Token 列表
46    tokens: Vec<Token<JasmTokenType>>,
47    /// 当前位置
48    position: usize,
49}
50
51impl<'input> ParserState<'input> {
52    /// 创建新的解析器状态
53    fn new(url: Option<Url>, source: &'input str, tokens: Vec<Token<JasmTokenType>>) -> Self {
54        Self { url, source, tokens, position: 0 }
55    }
56
57    /// 获取当前 token
58    fn current(&self) -> Option<&Token<JasmTokenType>> {
59        self.tokens.get(self.position)
60    }
61
62    /// 前进到下一个 token
63    fn advance(&mut self) -> Option<&Token<JasmTokenType>> {
64        if self.position < self.tokens.len() {
65            self.position += 1;
66        }
67        self.current()
68    }
69
70    /// 检查当前 token 是否匹配指定类型
71    fn check(&self, token_type: JasmTokenType) -> bool {
72        self.current().map(|t| t.token_type) == Some(token_type)
73    }
74
75    /// 消费指定类型的 token
76    fn consume(&mut self, token_type: JasmTokenType) -> Result<Token<JasmTokenType>> {
77        if self.check(token_type) {
78            let token = self.current().unwrap().clone();
79            self.advance();
80            Ok(token)
81        }
82        else {
83            Err(GaiaError::custom_error(format!(
84                "Expected {:?}, found {:?} at {:?}",
85                token_type,
86                self.current().map(|t| t.token_type),
87                self.location_from_token(self.current().unwrap())
88            )))
89        }
90    }
91
92    /// 跳过空白和注释
93    fn skip_whitespace_and_comments(&mut self) {
94        while let Some(token) = self.current() {
95            match token.token_type {
96                JasmTokenType::Whitespace | JasmTokenType::Comment => {
97                    self.advance();
98                }
99                _ => break,
100            }
101        }
102    }
103
104    /// 解析根节点
105    fn parse_root(&mut self) -> Result<JasmRoot> {
106        self.skip_whitespace_and_comments();
107
108        let class = self.parse_class()?;
109
110        Ok(JasmRoot { class })
111    }
112
113    /// 解析类定义
114    fn parse_class(&mut self) -> Result<JasmClass> {
115        // 解析访问修饰符
116        let mut modifiers = Vec::new();
117        while let Some(token) = self.current() {
118            match token.token_type {
119                JasmTokenType::Public => {
120                    modifiers.push("public".to_string());
121                    self.advance();
122                }
123                JasmTokenType::Private => {
124                    modifiers.push("private".to_string());
125                    self.advance();
126                }
127                JasmTokenType::Protected => {
128                    modifiers.push("protected".to_string());
129                    self.advance();
130                }
131                JasmTokenType::Static => {
132                    modifiers.push("static".to_string());
133                    self.advance();
134                }
135                JasmTokenType::Final => {
136                    modifiers.push("final".to_string());
137                    self.advance();
138                }
139                JasmTokenType::Super => {
140                    modifiers.push("super".to_string());
141                    self.advance();
142                }
143                JasmTokenType::Abstract => {
144                    modifiers.push("abstract".to_string());
145                    self.advance();
146                }
147                _ => break,
148            }
149            self.skip_whitespace_and_comments();
150        }
151
152        // 消费 "class" 关键字
153        self.consume(JasmTokenType::Class)?;
154        self.skip_whitespace_and_comments();
155
156        // 解析类名
157        let name_token = self.consume(JasmTokenType::Identifier)?;
158        let name = self.token_text(&name_token).to_string();
159        self.skip_whitespace_and_comments();
160
161        // 解析版本信息(可选)
162        let mut version = None;
163        if self.check(JasmTokenType::Version) {
164            self.advance(); // 消费 "version"
165            self.skip_whitespace_and_comments();
166            let version_token = self.consume(JasmTokenType::Number)?;
167            let version_text = self.token_text(&version_token).to_string(); // 克隆字符串
168
169            // 检查是否有冒号和次版本号
170            if self.check(JasmTokenType::Colon) {
171                self.advance(); // 消费 ":"
172                self.skip_whitespace_and_comments();
173                let minor_token = self.consume(JasmTokenType::Number)?;
174                let minor_text = self.token_text(&minor_token).to_string(); // 克隆字符串
175                version = Some(format!("{}:{}", version_text, minor_text));
176            }
177            else {
178                version = Some(version_text);
179            }
180            self.skip_whitespace_and_comments();
181        }
182
183        // 消费左大括号
184        self.consume(JasmTokenType::LeftBrace)?;
185        self.skip_whitespace_and_comments();
186
187        // 解析类体
188        let mut methods = Vec::new();
189        let mut fields = Vec::new();
190        let mut source_file = None;
191
192        while !self.check(JasmTokenType::RightBrace) && self.current().is_some() {
193            self.skip_whitespace_and_comments();
194
195            if let Some(token) = self.current() {
196                match token.token_type {
197                    JasmTokenType::Method
198                    | JasmTokenType::Public
199                    | JasmTokenType::Private
200                    | JasmTokenType::Protected
201                    | JasmTokenType::Static
202                    | JasmTokenType::Final => {
203                        methods.push(self.parse_method()?);
204                    }
205                    JasmTokenType::Field => {
206                        fields.push(self.parse_field()?);
207                    }
208                    JasmTokenType::SourceFile => {
209                        source_file = Some(self.parse_source_file()?);
210                    }
211                    _ => {
212                        return Err(GaiaError::custom_error(format!(
213                            "Unexpected token in class body: {:?} at {:?}",
214                            token.token_type,
215                            self.location_from_token(token)
216                        )));
217                    }
218                }
219            }
220            self.skip_whitespace_and_comments();
221        }
222
223        // 消费右大括号
224        self.consume(JasmTokenType::RightBrace)?;
225
226        Ok(JasmClass { modifiers, name, version, methods, fields, source_file })
227    }
228
229    /// 解析方法定义
230    fn parse_method(&mut self) -> Result<JasmMethod> {
231        // 解析访问修饰符
232        let mut modifiers = Vec::new();
233        while let Some(token) = self.current() {
234            match token.token_type {
235                JasmTokenType::Public => {
236                    modifiers.push("public".to_string());
237                    self.advance();
238                }
239                JasmTokenType::Private => {
240                    modifiers.push("private".to_string());
241                    self.advance();
242                }
243                JasmTokenType::Protected => {
244                    modifiers.push("protected".to_string());
245                    self.advance();
246                }
247                JasmTokenType::Static => {
248                    modifiers.push("static".to_string());
249                    self.advance();
250                }
251                JasmTokenType::Final => {
252                    modifiers.push("final".to_string());
253                    self.advance();
254                }
255                JasmTokenType::Synchronized => {
256                    modifiers.push("synchronized".to_string());
257                    self.advance();
258                }
259                JasmTokenType::Native => {
260                    modifiers.push("native".to_string());
261                    self.advance();
262                }
263                _ => break,
264            }
265            self.skip_whitespace_and_comments();
266        }
267
268        // 消费 "Method" 关键字
269        self.consume(JasmTokenType::Method)?;
270        self.skip_whitespace_and_comments();
271
272        // 解析方法名和描述符
273        let name_and_descriptor = self.parse_method_signature()?;
274        self.skip_whitespace_and_comments();
275
276        // 解析栈大小和局部变量数(可选)
277        let mut stack_size = None;
278        let mut locals_count = None;
279
280        if self.check(JasmTokenType::Stack) {
281            self.advance(); // 消费 "stack"
282            self.skip_whitespace_and_comments();
283            let stack_token = self.consume(JasmTokenType::Number)?;
284            stack_size = Some(self.token_text(&stack_token).parse().unwrap_or(0));
285            self.skip_whitespace_and_comments();
286        }
287
288        if self.check(JasmTokenType::Locals) {
289            self.advance(); // 消费 "locals"
290            self.skip_whitespace_and_comments();
291            let locals_token = self.consume(JasmTokenType::Number)?;
292            locals_count = Some(self.token_text(&locals_token).parse().unwrap_or(0));
293            self.skip_whitespace_and_comments();
294        }
295
296        // 消费左大括号
297        self.consume(JasmTokenType::LeftBrace)?;
298        self.skip_whitespace_and_comments();
299
300        // 解析方法体指令
301        let mut instructions = Vec::new();
302        while !self.check(JasmTokenType::RightBrace) && self.current().is_some() {
303            self.skip_whitespace_and_comments();
304            if let Some(instruction) = self.parse_instruction()? {
305                instructions.push(instruction);
306            }
307            self.skip_whitespace_and_comments();
308        }
309
310        // 消费右大括号
311        self.consume(JasmTokenType::RightBrace)?;
312
313        Ok(JasmMethod { modifiers, name_and_descriptor, stack_size, locals_count, instructions })
314    }
315
316    /// 解析方法签名(名称和描述符)
317    fn parse_method_signature(&mut self) -> Result<String> {
318        let mut signature = String::new();
319
320        // 解析方法名(可能包含特殊字符如 <init>)
321        if self.check(JasmTokenType::StringLiteral) || self.check(JasmTokenType::Identifier) {
322            let token = self.current().unwrap();
323            let text = self.token_text(token);
324            if text.starts_with('"') && text.ends_with('"') {
325                signature.push_str(&text[1..text.len() - 1]); // 去掉引号
326            }
327            else {
328                signature.push_str(text);
329            }
330            self.advance();
331        }
332
333        self.skip_whitespace_and_comments();
334
335        // 消费冒号
336        if self.check(JasmTokenType::Colon) {
337            signature.push(':');
338            self.advance();
339            self.skip_whitespace_and_comments();
340        }
341
342        // 解析类型描述符
343        if self.check(JasmTokenType::TypeDescriptor) || self.check(JasmTokenType::StringLiteral) {
344            let token = self.current().unwrap();
345            let text = self.token_text(token);
346            if text.starts_with('"') && text.ends_with('"') {
347                signature.push_str(&text[1..text.len() - 1]); // 去掉引号
348            }
349            else {
350                signature.push_str(text);
351            }
352            self.advance();
353        }
354
355        Ok(signature)
356    }
357
358    /// 解析指令
359    fn parse_instruction(&mut self) -> Result<Option<JasmInstruction>> {
360        if let Some(token) = self.current() {
361            match token.token_type {
362                // 简单指令
363                JasmTokenType::ALoad0
364                | JasmTokenType::ALoad1
365                | JasmTokenType::ALoad2
366                | JasmTokenType::ALoad3
367                | JasmTokenType::ILoad0
368                | JasmTokenType::ILoad1
369                | JasmTokenType::ILoad2
370                | JasmTokenType::ILoad3
371                | JasmTokenType::Return
372                | JasmTokenType::IReturn
373                | JasmTokenType::AReturn
374                | JasmTokenType::Nop
375                | JasmTokenType::Dup
376                | JasmTokenType::Pop => {
377                    let instruction_name = self.token_text(token).to_string();
378                    self.advance();
379                    self.skip_whitespace_and_comments();
380
381                    // 消费分号
382                    if self.check(JasmTokenType::Semicolon) {
383                        self.advance();
384                    }
385
386                    Ok(Some(JasmInstruction::Simple(instruction_name)))
387                }
388
389                // 带参数的指令
390                JasmTokenType::Ldc | JasmTokenType::LdcW | JasmTokenType::Ldc2W => {
391                    let instruction_name = self.token_text(token).to_string();
392                    self.advance();
393                    self.skip_whitespace_and_comments();
394
395                    // 解析参数
396                    let argument = if self.check(JasmTokenType::String) {
397                        self.advance(); // 消费 "String"
398                        self.skip_whitespace_and_comments();
399                        if self.check(JasmTokenType::StringLiteral) {
400                            let arg_token = self.current().unwrap();
401                            let arg_text = self.token_text(arg_token).to_string(); // 克隆字符串
402                            self.advance();
403                            format!("String {}", arg_text)
404                        }
405                        else {
406                            return Err(GaiaError::custom_error(format!(
407                                "Expected string literal after String at {:?}",
408                                self.location_from_token(self.current().unwrap_or(&Token {
409                                    token_type: JasmTokenType::Eof,
410                                    position: SourcePosition { line: 0, column: 0, offset: 0, length: 0 }
411                                }))
412                            )));
413                        }
414                    }
415                    else if self.check(JasmTokenType::StringLiteral) || self.check(JasmTokenType::Number) {
416                        let arg_token = self.current().unwrap();
417                        let arg_text = self.token_text(arg_token).to_string();
418                        self.advance();
419                        arg_text
420                    }
421                    else {
422                        return Err(GaiaError::custom_error(format!(
423                            "Expected argument for ldc instruction at {:?}",
424                            self.location_from_token(self.current().unwrap_or(&Token {
425                                token_type: JasmTokenType::Eof,
426                                position: SourcePosition { line: 0, column: 0, offset: 0, length: 0 }
427                            }))
428                        )));
429                    };
430
431                    self.skip_whitespace_and_comments();
432
433                    // 消费分号
434                    if self.check(JasmTokenType::Semicolon) {
435                        self.advance();
436                    }
437
438                    Ok(Some(JasmInstruction::WithArgument { instruction: instruction_name, argument }))
439                }
440
441                // 方法调用指令
442                JasmTokenType::InvokeSpecial
443                | JasmTokenType::InvokeVirtual
444                | JasmTokenType::InvokeStatic
445                | JasmTokenType::InvokeInterface => {
446                    let instruction_name = self.token_text(token).to_string();
447                    self.advance();
448                    self.skip_whitespace_and_comments();
449
450                    // 消费 "Method" 关键字
451                    self.consume(JasmTokenType::Method)?;
452                    self.skip_whitespace_and_comments();
453
454                    // 解析方法引用
455                    let method_ref = self.parse_method_reference()?;
456                    self.skip_whitespace_and_comments();
457
458                    // 消费分号
459                    if self.check(JasmTokenType::Semicolon) {
460                        self.advance();
461                    }
462
463                    Ok(Some(JasmInstruction::MethodCall { instruction: instruction_name, method_ref }))
464                }
465
466                // 字段访问指令
467                JasmTokenType::GetStatic | JasmTokenType::PutStatic | JasmTokenType::GetField | JasmTokenType::PutField => {
468                    let instruction_name = self.token_text(token).to_string();
469                    self.advance();
470                    self.skip_whitespace_and_comments();
471
472                    // 消费 "Field" 关键字
473                    self.consume(JasmTokenType::Field)?;
474                    self.skip_whitespace_and_comments();
475
476                    // 解析字段引用
477                    let field_ref = self.parse_field_reference()?;
478                    self.skip_whitespace_and_comments();
479
480                    // 消费分号
481                    if self.check(JasmTokenType::Semicolon) {
482                        self.advance();
483                    }
484
485                    Ok(Some(JasmInstruction::FieldAccess { instruction: instruction_name, field_ref }))
486                }
487
488                _ => {
489                    // 跳过未知的 token
490                    self.advance();
491                    Ok(None)
492                }
493            }
494        }
495        else {
496            Ok(None)
497        }
498    }
499
500    /// 解析方法引用
501    fn parse_method_reference(&mut self) -> Result<String> {
502        let mut method_ref = String::new();
503
504        // 解析类名
505        if self.check(JasmTokenType::Identifier) {
506            let token = self.current().unwrap();
507            method_ref.push_str(self.token_text(token));
508            self.advance();
509        }
510
511        // 消费点号
512        if self.check(JasmTokenType::Dot) {
513            method_ref.push('.');
514            self.advance();
515        }
516
517        // 解析方法名和描述符
518        if self.check(JasmTokenType::StringLiteral) || self.check(JasmTokenType::Identifier) {
519            let token = self.current().unwrap();
520            let text = self.token_text(token);
521            if text.starts_with('"') && text.ends_with('"') {
522                method_ref.push_str(&text[1..text.len() - 1]); // 去掉引号
523            }
524            else {
525                method_ref.push_str(text);
526            }
527            self.advance();
528        }
529
530        // 消费冒号
531        if self.check(JasmTokenType::Colon) {
532            method_ref.push(':');
533            self.advance();
534        }
535
536        // 解析类型描述符
537        if self.check(JasmTokenType::TypeDescriptor) || self.check(JasmTokenType::StringLiteral) {
538            let token = self.current().unwrap();
539            let text = self.token_text(token);
540            if text.starts_with('"') && text.ends_with('"') {
541                method_ref.push_str(&text[1..text.len() - 1]); // 去掉引号
542            }
543            else {
544                method_ref.push_str(text);
545            }
546            self.advance();
547        }
548
549        Ok(method_ref)
550    }
551
552    /// 解析字段引用
553    fn parse_field_reference(&mut self) -> Result<String> {
554        let mut field_ref = String::new();
555
556        // 解析类名
557        if self.check(JasmTokenType::Identifier) {
558            let token = self.current().unwrap();
559            field_ref.push_str(self.token_text(token));
560            self.advance();
561        }
562
563        // 消费点号
564        if self.check(JasmTokenType::Dot) {
565            field_ref.push('.');
566            self.advance();
567        }
568
569        // 解析字段名
570        if self.check(JasmTokenType::Identifier) {
571            let token = self.current().unwrap();
572            field_ref.push_str(self.token_text(token));
573            self.advance();
574        }
575
576        // 消费冒号
577        if self.check(JasmTokenType::Colon) {
578            field_ref.push(':');
579            self.advance();
580        }
581
582        // 解析类型描述符
583        if self.check(JasmTokenType::TypeDescriptor) || self.check(JasmTokenType::StringLiteral) {
584            let token = self.current().unwrap();
585            let text = self.token_text(token);
586            if text.starts_with('"') && text.ends_with('"') {
587                field_ref.push_str(&text[1..text.len() - 1]); // 去掉引号
588            }
589            else {
590                field_ref.push_str(text);
591            }
592            self.advance();
593        }
594
595        Ok(field_ref)
596    }
597
598    /// 解析字段定义
599    fn parse_field(&mut self) -> Result<JasmField> {
600        // 解析访问修饰符
601        let mut modifiers = Vec::new();
602        while let Some(token) = self.current() {
603            match token.token_type {
604                JasmTokenType::Public => {
605                    modifiers.push("public".to_string());
606                    self.advance();
607                }
608                JasmTokenType::Private => {
609                    modifiers.push("private".to_string());
610                    self.advance();
611                }
612                JasmTokenType::Protected => {
613                    modifiers.push("protected".to_string());
614                    self.advance();
615                }
616                JasmTokenType::Static => {
617                    modifiers.push("static".to_string());
618                    self.advance();
619                }
620                JasmTokenType::Final => {
621                    modifiers.push("final".to_string());
622                    self.advance();
623                }
624                _ => break,
625            }
626            self.skip_whitespace_and_comments();
627        }
628
629        // 消费 "Field" 关键字
630        self.consume(JasmTokenType::Field)?;
631        self.skip_whitespace_and_comments();
632
633        // 解析字段名和描述符
634        let name_and_descriptor = self.parse_field_signature()?;
635        self.skip_whitespace_and_comments();
636
637        // 消费分号
638        if self.check(JasmTokenType::Semicolon) {
639            self.advance();
640        }
641
642        Ok(JasmField { modifiers, name_and_descriptor })
643    }
644
645    /// 解析字段签名
646    fn parse_field_signature(&mut self) -> Result<String> {
647        let mut signature = String::new();
648
649        // 解析字段名
650        if self.check(JasmTokenType::Identifier) {
651            let token = self.current().unwrap();
652            signature.push_str(self.token_text(token));
653            self.advance();
654        }
655
656        self.skip_whitespace_and_comments();
657
658        // 消费冒号
659        if self.check(JasmTokenType::Colon) {
660            signature.push(':');
661            self.advance();
662            self.skip_whitespace_and_comments();
663        }
664
665        // 解析类型描述符
666        if self.check(JasmTokenType::TypeDescriptor) || self.check(JasmTokenType::StringLiteral) {
667            let token = self.current().unwrap();
668            let text = self.token_text(token);
669            if text.starts_with('"') && text.ends_with('"') {
670                signature.push_str(&text[1..text.len() - 1]); // 去掉引号
671            }
672            else {
673                signature.push_str(text);
674            }
675            self.advance();
676        }
677
678        Ok(signature)
679    }
680
681    /// 解析源文件信息
682    fn parse_source_file(&mut self) -> Result<String> {
683        // 消费 "SourceFile" 关键字
684        self.consume(JasmTokenType::SourceFile)?;
685        self.skip_whitespace_and_comments();
686
687        // 解析文件名
688        let filename_token = self.consume(JasmTokenType::StringLiteral)?;
689        let filename = self.token_text(&filename_token).to_string(); // 克隆字符串
690
691        // 去掉引号
692        let filename =
693            if filename.starts_with('"') && filename.ends_with('"') { &filename[1..filename.len() - 1] } else { &filename };
694
695        self.skip_whitespace_and_comments();
696
697        // 消费分号
698        if self.check(JasmTokenType::Semicolon) {
699            self.advance();
700        }
701
702        Ok(filename.to_string())
703    }
704
705    /// 获取 token 的文本内容
706    fn token_text(&self, token: &Token<JasmTokenType>) -> &str {
707        let range = token.get_range();
708        &self.source[range]
709    }
710
711    /// 从 token 创建源位置
712    fn location_from_token(&self, token: &Token<JasmTokenType>) -> SourceLocation {
713        SourceLocation { line: token.position.line, column: token.position.column, url: self.url.clone().map(|u| u.clone()) }
714    }
715}
716
717impl Default for JasmParser {
718    fn default() -> Self {
719        Self::new(None)
720    }
721}