add: grammar parsers up to statement.
All checks were successful
Run Unit Tests / Run-Unit-Tests (push) Successful in 1s
All checks were successful
Run Unit Tests / Run-Unit-Tests (push) Successful in 1s
This commit is contained in:
parent
70f4a48039
commit
e278a5dcc6
|
@ -1,13 +1,14 @@
|
||||||
use crate::parser::syntax_tree::{BinaryNodeType, SyntaxNode, UnaryNodeType};
|
use crate::parser::syntax_tree::{BinaryNodeType, SyntaxNode, UnaryNodeType};
|
||||||
use crate::tokenizer::{LexicalTokenSpan, LexicalTokenType};
|
use crate::tokenizer::{LexicalTokenSpan, LexicalTokenType};
|
||||||
use nom::branch::alt;
|
use nom::branch::alt;
|
||||||
use nom::combinator::map;
|
use nom::combinator::{map, opt};
|
||||||
use nom::multi::many0;
|
use nom::multi::{many0, separated_list0};
|
||||||
use nom::sequence::tuple;
|
use nom::sequence::tuple;
|
||||||
use nom::IResult;
|
use nom::IResult;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
/// 匹配词法令牌所用的宏展开
|
||||||
macro_rules! lexical {
|
macro_rules! lexical {
|
||||||
(Integer) => {
|
(Integer) => {
|
||||||
nom::bytes::complete::tag(
|
nom::bytes::complete::tag(
|
||||||
|
@ -86,12 +87,61 @@ fn identifier_parser(cursor: LexicalTokenSpan) -> IResult<LexicalTokenSpan, Rc<R
|
||||||
)(cursor)
|
)(cursor)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type LeftValueParseType<'a> = (Rc<RefCell<SyntaxNode>>, Vec<(LexicalTokenSpan<'a>, Rc<RefCell<SyntaxNode>>, LexicalTokenSpan<'a>)>);
|
||||||
|
|
||||||
|
fn left_value_parser(cursor: LexicalTokenSpan) -> IResult<LexicalTokenSpan, Rc<RefCell<SyntaxNode>>> {
|
||||||
|
map(
|
||||||
|
tuple((
|
||||||
|
identifier_parser,
|
||||||
|
many0(tuple((
|
||||||
|
lexical!(Delimiter("[")),
|
||||||
|
expression_parser,
|
||||||
|
lexical!(Delimiter("]"))
|
||||||
|
)))
|
||||||
|
)),
|
||||||
|
|(first, second): LeftValueParseType| {
|
||||||
|
let mut node = first;
|
||||||
|
|
||||||
|
for (_, index_expression, _) in second {
|
||||||
|
node = SyntaxNode::binary_node(BinaryNodeType::Index, &node, &index_expression);
|
||||||
|
}
|
||||||
|
|
||||||
|
node
|
||||||
|
},
|
||||||
|
)(cursor)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 处理没有任何后缀(即数组下标)的基本表达式
|
||||||
fn primary_parser(curser: LexicalTokenSpan) -> IResult<LexicalTokenSpan, Rc<RefCell<SyntaxNode>>> {
|
fn primary_parser(curser: LexicalTokenSpan) -> IResult<LexicalTokenSpan, Rc<RefCell<SyntaxNode>>> {
|
||||||
|
// primary_parser -> '(' expression_parser ')' | identifier '(' [ expression_parser (',' expression_parser)* ] ')' |
|
||||||
|
// left_value_parser | identifier_parser | integer_node_parser | float_node_parser | literal_string_node_parser
|
||||||
alt((
|
alt((
|
||||||
|
map(
|
||||||
|
tuple((
|
||||||
|
lexical!(Delimiter ("(")),
|
||||||
|
expression_parser,
|
||||||
|
lexical!(Delimiter (")"))
|
||||||
|
)),
|
||||||
|
|(_, expression, _)| {
|
||||||
|
expression
|
||||||
|
},
|
||||||
|
),
|
||||||
|
map(
|
||||||
|
tuple((
|
||||||
|
identifier_parser,
|
||||||
|
lexical!(Delimiter("(")),
|
||||||
|
separated_list0(lexical!(Delimiter (",")), expression_parser),
|
||||||
|
lexical!(Delimiter(")"))
|
||||||
|
)),
|
||||||
|
|(identifier, _, arguments, _)| {
|
||||||
|
SyntaxNode::function_call(&identifier, &arguments)
|
||||||
|
},
|
||||||
|
),
|
||||||
|
left_value_parser,
|
||||||
identifier_parser,
|
identifier_parser,
|
||||||
integer_node_parser,
|
integer_node_parser,
|
||||||
float_node_parser,
|
float_node_parser,
|
||||||
literal_string_node_parser
|
literal_string_node_parser,
|
||||||
))(curser)
|
))(curser)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -328,6 +378,148 @@ fn condition_parser(cursor: LexicalTokenSpan) -> IResult<LexicalTokenSpan, Rc<Re
|
||||||
or_parser(cursor)
|
or_parser(cursor)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn expression_parser(cursor: LexicalTokenSpan) -> IResult<LexicalTokenSpan, Rc<RefCell<SyntaxNode>>> {
|
||||||
|
add_parser(cursor)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn assign_statement_parser(cursor: LexicalTokenSpan) -> IResult<LexicalTokenSpan, Rc<RefCell<SyntaxNode>>> {
|
||||||
|
map(
|
||||||
|
tuple((
|
||||||
|
left_value_parser,
|
||||||
|
lexical!(Operator("=")),
|
||||||
|
expression_parser,
|
||||||
|
lexical!(Delimiter(";"))
|
||||||
|
)),
|
||||||
|
|(left_value, _, expresison, _)| {
|
||||||
|
SyntaxNode::assign_statement(&left_value, &expresison)
|
||||||
|
},
|
||||||
|
)(cursor)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn expression_statement_parser(cursor: LexicalTokenSpan) -> IResult<LexicalTokenSpan, Rc<RefCell<SyntaxNode>>> {
|
||||||
|
map(
|
||||||
|
tuple((
|
||||||
|
opt(expression_parser),
|
||||||
|
lexical!(Delimiter(";"))
|
||||||
|
)),
|
||||||
|
|(expression, _)| {
|
||||||
|
match expression {
|
||||||
|
Some(expression) => SyntaxNode::expression_statement(&expression),
|
||||||
|
None => SyntaxNode::expression_statement(&SyntaxNode::unit())
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)(cursor)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn if_statement_parser(cursor: LexicalTokenSpan) -> IResult<LexicalTokenSpan, Rc<RefCell<SyntaxNode>>> {
|
||||||
|
map(
|
||||||
|
tuple((
|
||||||
|
lexical!(Keyword("if")),
|
||||||
|
lexical!(Delimiter("(")),
|
||||||
|
condition_parser,
|
||||||
|
lexical!(Delimiter(")")),
|
||||||
|
statement_parser,
|
||||||
|
opt(
|
||||||
|
tuple((
|
||||||
|
lexical!(Keyword("else")),
|
||||||
|
statement_parser
|
||||||
|
))
|
||||||
|
)
|
||||||
|
)),
|
||||||
|
|(_, _, condition, _, if_statement, else_part)| {
|
||||||
|
let else_statement = match else_part {
|
||||||
|
Some(else_part) => else_part.1,
|
||||||
|
None => SyntaxNode::unit()
|
||||||
|
};
|
||||||
|
|
||||||
|
SyntaxNode::if_statement(&condition, &if_statement, &else_statement)
|
||||||
|
},
|
||||||
|
)(cursor)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn while_statement_parser(cursor: LexicalTokenSpan) -> IResult<LexicalTokenSpan, Rc<RefCell<SyntaxNode>>> {
|
||||||
|
map(
|
||||||
|
tuple((
|
||||||
|
lexical!(Keyword("while")),
|
||||||
|
lexical!(Delimiter("(")),
|
||||||
|
condition_parser,
|
||||||
|
lexical!(Delimiter(")")),
|
||||||
|
statement_parser
|
||||||
|
)),
|
||||||
|
|(_, _, condition, _, statement)| {
|
||||||
|
SyntaxNode::while_statement(&condition, &statement)
|
||||||
|
},
|
||||||
|
)(cursor)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn break_statement_parser(cursor: LexicalTokenSpan) -> IResult<LexicalTokenSpan, Rc<RefCell<SyntaxNode>>> {
|
||||||
|
map(
|
||||||
|
tuple((
|
||||||
|
lexical!(Keyword("break")),
|
||||||
|
lexical!(Delimiter(";"))
|
||||||
|
)),
|
||||||
|
|_| {
|
||||||
|
SyntaxNode::break_statement()
|
||||||
|
},
|
||||||
|
)(cursor)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn continue_statement_parser(cursor: LexicalTokenSpan) -> IResult<LexicalTokenSpan, Rc<RefCell<SyntaxNode>>> {
|
||||||
|
map(
|
||||||
|
tuple((
|
||||||
|
lexical!(Keyword("continue")),
|
||||||
|
lexical!(Delimiter(";"))
|
||||||
|
)),
|
||||||
|
|_| {
|
||||||
|
SyntaxNode::continue_statement()
|
||||||
|
},
|
||||||
|
)(cursor)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn return_statement_parser(cursor: LexicalTokenSpan) -> IResult<LexicalTokenSpan, Rc<RefCell<SyntaxNode>>> {
|
||||||
|
map(
|
||||||
|
tuple((
|
||||||
|
lexical!(Keyword("return")),
|
||||||
|
opt(expression_parser),
|
||||||
|
lexical!(Delimiter(";"))
|
||||||
|
)),
|
||||||
|
|(_, expression, _)| {
|
||||||
|
match expression {
|
||||||
|
None => SyntaxNode::return_statement(&SyntaxNode::unit()),
|
||||||
|
Some(expression) => SyntaxNode::return_statement(&expression)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)(cursor)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn statement_parser(cursor: LexicalTokenSpan) -> IResult<LexicalTokenSpan, Rc<RefCell<SyntaxNode>>> {
|
||||||
|
alt((
|
||||||
|
if_statement_parser,
|
||||||
|
while_statement_parser,
|
||||||
|
break_statement_parser,
|
||||||
|
continue_statement_parser,
|
||||||
|
return_statement_parser,
|
||||||
|
block_parser,
|
||||||
|
assign_statement_parser,
|
||||||
|
expression_statement_parser,
|
||||||
|
))(cursor)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn block_parser(cursor: LexicalTokenSpan) -> IResult<LexicalTokenSpan, Rc<RefCell<SyntaxNode>>> {
|
||||||
|
map(
|
||||||
|
tuple((
|
||||||
|
lexical!(Delimiter("{")),
|
||||||
|
many0(alt((
|
||||||
|
statement_parser,
|
||||||
|
))),
|
||||||
|
lexical!(Delimiter("}"))
|
||||||
|
)),
|
||||||
|
|(_, statements, _): (LexicalTokenSpan, Vec<Rc<RefCell<SyntaxNode>>>, LexicalTokenSpan)| {
|
||||||
|
SyntaxNode::block(&statements)
|
||||||
|
},
|
||||||
|
)(cursor)
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -511,4 +703,190 @@ mod test {
|
||||||
|
|
||||||
validate_syntax_node("i != 1 && i != 2", &node.borrow().node_type, condition_parser);
|
validate_syntax_node("i != 1 && i != 2", &node.borrow().node_type, condition_parser);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn expression_with_parethness_test() {
|
||||||
|
let node = SyntaxNode::binary_node(BinaryNodeType::Multiply,
|
||||||
|
&SyntaxNode::const_integer(3),
|
||||||
|
&SyntaxNode::binary_node(BinaryNodeType::Subtract,
|
||||||
|
&SyntaxNode::const_integer(5),
|
||||||
|
&SyntaxNode::const_integer(2)));
|
||||||
|
|
||||||
|
validate_syntax_node("3 * (5 - 2)", &node.borrow().node_type, expression_parser);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn array_index_expression_test() {
|
||||||
|
let node = SyntaxNode::binary_node(BinaryNodeType::Index,
|
||||||
|
&SyntaxNode::identifier("array".to_owned()),
|
||||||
|
&SyntaxNode::const_integer(0));
|
||||||
|
|
||||||
|
validate_syntax_node("array[0]", &node.borrow().node_type, expression_parser);
|
||||||
|
|
||||||
|
let node = SyntaxNode::binary_node(BinaryNodeType::Index,
|
||||||
|
&SyntaxNode::binary_node(BinaryNodeType::Index,
|
||||||
|
&SyntaxNode::identifier("array".to_owned()),
|
||||||
|
&SyntaxNode::const_integer(0)),
|
||||||
|
&SyntaxNode::const_integer(0));
|
||||||
|
|
||||||
|
validate_syntax_node("array[0][0]", &node.borrow().node_type, expression_parser);
|
||||||
|
|
||||||
|
let node = SyntaxNode::binary_node(BinaryNodeType::Index,
|
||||||
|
&SyntaxNode::identifier("array".to_owned()),
|
||||||
|
&SyntaxNode::binary_node(BinaryNodeType::Add,
|
||||||
|
&SyntaxNode::identifier("i".to_owned()),
|
||||||
|
&SyntaxNode::const_integer(1)));
|
||||||
|
|
||||||
|
validate_syntax_node("array[i + 1]", &node.borrow().node_type, expression_parser);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn function_call_expression_test() {
|
||||||
|
let node = SyntaxNode::function_call(&SyntaxNode::identifier("empty_function".to_owned()),
|
||||||
|
&vec![]);
|
||||||
|
|
||||||
|
validate_syntax_node("empty_function()", &node.borrow().node_type, expression_parser);
|
||||||
|
|
||||||
|
let node = SyntaxNode::function_call(&SyntaxNode::identifier("add".to_owned()),
|
||||||
|
&vec![SyntaxNode::const_integer(1), SyntaxNode::const_integer(1)]);
|
||||||
|
|
||||||
|
validate_syntax_node("add(1, 1)", &node.borrow().node_type, expression_parser);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn assign_statement_test() {
|
||||||
|
let node = SyntaxNode::assign_statement(
|
||||||
|
&SyntaxNode::identifier("i".to_owned()),
|
||||||
|
&SyntaxNode::const_integer(1),
|
||||||
|
);
|
||||||
|
|
||||||
|
validate_syntax_node("i = 1;", &node.borrow().node_type, assign_statement_parser);
|
||||||
|
validate_syntax_node("i = 1;", &node.borrow().node_type, statement_parser);
|
||||||
|
|
||||||
|
let node = SyntaxNode::assign_statement(
|
||||||
|
&SyntaxNode::binary_node(BinaryNodeType::Index,
|
||||||
|
&SyntaxNode::identifier("array".to_owned()),
|
||||||
|
&SyntaxNode::const_integer(10)),
|
||||||
|
&SyntaxNode::identifier("a".to_owned()),
|
||||||
|
);
|
||||||
|
|
||||||
|
validate_syntax_node("array[10] = a;", &node.borrow().node_type, assign_statement_parser);
|
||||||
|
validate_syntax_node("array[10] = a;", &node.borrow().node_type, statement_parser);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn expression_statement_test() {
|
||||||
|
let node = SyntaxNode::expression_statement(&SyntaxNode::unit());
|
||||||
|
|
||||||
|
validate_syntax_node(";", &node.borrow().node_type, expression_statement_parser);
|
||||||
|
validate_syntax_node(";", &node.borrow().node_type, statement_parser);
|
||||||
|
|
||||||
|
let node = SyntaxNode::expression_statement(&SyntaxNode::binary_node(
|
||||||
|
BinaryNodeType::Add,
|
||||||
|
&SyntaxNode::const_integer(1),
|
||||||
|
&SyntaxNode::const_integer(1),
|
||||||
|
));
|
||||||
|
|
||||||
|
validate_syntax_node("1 + 1;", &node.borrow().node_type, expression_statement_parser);
|
||||||
|
validate_syntax_node("1 + 1;", &node.borrow().node_type, statement_parser);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn if_statement_test() {
|
||||||
|
let node = SyntaxNode::if_statement(
|
||||||
|
&SyntaxNode::binary_node(BinaryNodeType::Equal,
|
||||||
|
&SyntaxNode::identifier("i".to_owned()), &SyntaxNode::const_integer(1)),
|
||||||
|
&SyntaxNode::assign_statement(&SyntaxNode::identifier("i".to_owned()),
|
||||||
|
&SyntaxNode::const_integer(2)),
|
||||||
|
&SyntaxNode::assign_statement(&SyntaxNode::identifier("i".to_owned()),
|
||||||
|
&SyntaxNode::const_integer(1)),
|
||||||
|
);
|
||||||
|
|
||||||
|
validate_syntax_node("if (i == 1) i = 2; else i = 1;", &node.borrow().node_type, if_statement_parser);
|
||||||
|
validate_syntax_node("if (i == 1) i = 2; else i = 1;", &node.borrow().node_type, statement_parser);
|
||||||
|
|
||||||
|
let node = SyntaxNode::if_statement(
|
||||||
|
&SyntaxNode::binary_node(BinaryNodeType::Equal,
|
||||||
|
&SyntaxNode::identifier("i".to_owned()), &SyntaxNode::const_integer(1)),
|
||||||
|
&SyntaxNode::assign_statement(&SyntaxNode::identifier("i".to_owned()),
|
||||||
|
&SyntaxNode::const_integer(2)),
|
||||||
|
&SyntaxNode::unit()
|
||||||
|
);
|
||||||
|
|
||||||
|
validate_syntax_node("if (i == 1) i = 2;", &node.borrow().node_type, if_statement_parser);
|
||||||
|
validate_syntax_node("if (i == 1) i = 2;", &node.borrow().node_type, statement_parser);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn multiplx_if_statement_test() {
|
||||||
|
let node = SyntaxNode::if_statement(
|
||||||
|
&SyntaxNode::binary_node(BinaryNodeType::Equal,
|
||||||
|
&SyntaxNode::identifier("i".to_owned()), &SyntaxNode::const_integer(1)),
|
||||||
|
&SyntaxNode::if_statement(
|
||||||
|
&SyntaxNode::binary_node(BinaryNodeType::Equal,
|
||||||
|
&SyntaxNode::identifier("i".to_owned()), &SyntaxNode::const_integer(2)),
|
||||||
|
&SyntaxNode::assign_statement(&SyntaxNode::identifier("i".to_owned()),
|
||||||
|
&SyntaxNode::const_integer(2)),
|
||||||
|
&SyntaxNode::assign_statement(&SyntaxNode::identifier("i".to_owned()),
|
||||||
|
&SyntaxNode::const_integer(1))
|
||||||
|
),
|
||||||
|
&SyntaxNode::unit()
|
||||||
|
);
|
||||||
|
|
||||||
|
validate_syntax_node("if (i == 1) if (i == 2) i = 2; else i = 1;", &node.borrow().node_type, if_statement_parser);
|
||||||
|
validate_syntax_node("if (i == 1) if (i == 2) i = 2; else i = 1;", &node.borrow().node_type, statement_parser);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn while_statement_test() {
|
||||||
|
let node = SyntaxNode::while_statement(
|
||||||
|
&SyntaxNode::binary_node(BinaryNodeType::NotEqual,
|
||||||
|
&SyntaxNode::identifier("i".to_owned()),
|
||||||
|
&SyntaxNode::const_integer(10)),
|
||||||
|
&SyntaxNode::assign_statement(
|
||||||
|
&SyntaxNode::identifier("i".to_owned()),
|
||||||
|
&SyntaxNode::binary_node(BinaryNodeType::Add,
|
||||||
|
&SyntaxNode::identifier("i".to_owned()),
|
||||||
|
&SyntaxNode::const_integer(1))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
validate_syntax_node("while (i != 10 ) i = i + 1;", &node.borrow().node_type, while_statement_parser);
|
||||||
|
validate_syntax_node("while (i != 10 ) i = i + 1;", &node.borrow().node_type, statement_parser);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn break_statement_test() {
|
||||||
|
let node = SyntaxNode::break_statement();
|
||||||
|
|
||||||
|
validate_syntax_node("break;", &node.borrow().node_type, break_statement_parser);
|
||||||
|
validate_syntax_node("break;", &node.borrow().node_type, statement_parser);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn continue_statement_test() {
|
||||||
|
let node = SyntaxNode::continue_statement();
|
||||||
|
|
||||||
|
validate_syntax_node("continue;", &node.borrow().node_type, continue_statement_parser);
|
||||||
|
validate_syntax_node("continue;", &node.borrow().node_type, statement_parser);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn return_statement_test() {
|
||||||
|
let node = SyntaxNode::return_statement(
|
||||||
|
&SyntaxNode::binary_node(BinaryNodeType::Add,
|
||||||
|
&SyntaxNode::const_integer(1),
|
||||||
|
&SyntaxNode::const_integer(1))
|
||||||
|
);
|
||||||
|
|
||||||
|
validate_syntax_node("return 1 + 1;", &node.borrow().node_type, return_statement_parser);
|
||||||
|
validate_syntax_node("return 1 + 1;", &node.borrow().node_type, statement_parser);
|
||||||
|
|
||||||
|
let node = SyntaxNode::return_statement(
|
||||||
|
&SyntaxNode::unit()
|
||||||
|
);
|
||||||
|
|
||||||
|
validate_syntax_node("return;", &node.borrow().node_type, return_statement_parser);
|
||||||
|
validate_syntax_node("return;", &node.borrow().node_type, statement_parser);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
use nom::IResult;
|
||||||
|
|
||||||
/// 单元表达式类型
|
/// 单元表达式类型
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
|
@ -32,6 +33,7 @@ pub enum BinaryNodeType {
|
||||||
NotEqual,
|
NotEqual,
|
||||||
And,
|
And,
|
||||||
Or,
|
Or,
|
||||||
|
Index,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 双元表达式节点
|
/// 双元表达式节点
|
||||||
|
@ -42,15 +44,59 @@ pub struct BinaryNode {
|
||||||
pub right: Rc<RefCell<SyntaxNode>>,
|
pub right: Rc<RefCell<SyntaxNode>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq)]
|
||||||
|
pub struct FunctionCallNode {
|
||||||
|
pub function: Rc<RefCell<SyntaxNode>>,
|
||||||
|
pub arguments: Vec<Rc<RefCell<SyntaxNode>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq)]
|
||||||
|
pub enum BasicTypes {
|
||||||
|
Void,
|
||||||
|
Integer,
|
||||||
|
Float,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq)]
|
||||||
|
pub struct IfStatementNode {
|
||||||
|
pub condition: Rc<RefCell<SyntaxNode>>,
|
||||||
|
pub if_statement: Rc<RefCell<SyntaxNode>>,
|
||||||
|
pub else_statement: Rc<RefCell<SyntaxNode>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq)]
|
||||||
|
pub struct WhileStatmentNode {
|
||||||
|
pub condition: Rc<RefCell<SyntaxNode>>,
|
||||||
|
pub statement: Rc<RefCell<SyntaxNode>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq)]
|
||||||
|
pub struct AssignStatmentNode {
|
||||||
|
pub left_value: Rc<RefCell<SyntaxNode>>,
|
||||||
|
pub expression: Rc<RefCell<SyntaxNode>>,
|
||||||
|
}
|
||||||
|
|
||||||
/// 语法分析树节点类型
|
/// 语法分析树节点类型
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub enum SyntaxNodeType {
|
pub enum SyntaxNodeType {
|
||||||
|
/// 空白的语法分析树节点
|
||||||
|
Unit,
|
||||||
|
BreakNode,
|
||||||
|
ContinueNode,
|
||||||
ConstIntegerNode(u32),
|
ConstIntegerNode(u32),
|
||||||
ConstFloatNode(f32),
|
ConstFloatNode(f32),
|
||||||
LiteralStringNode(String),
|
LiteralStringNode(String),
|
||||||
IdentifierNode(String),
|
IdentifierNode(String),
|
||||||
UnaryExpression(UnaryNode),
|
UnaryExpression(UnaryNode),
|
||||||
BinaryExpression(BinaryNode),
|
BinaryExpression(BinaryNode),
|
||||||
|
FunctionCall(FunctionCallNode),
|
||||||
|
IfStatement(IfStatementNode),
|
||||||
|
WhileStatement(WhileStatmentNode),
|
||||||
|
AssignStatement(AssignStatmentNode),
|
||||||
|
ExpressionStatement(Rc<RefCell<SyntaxNode>>),
|
||||||
|
ReturnStatement(Rc<RefCell<SyntaxNode>>),
|
||||||
|
Block(Vec<Rc<RefCell<SyntaxNode>>>),
|
||||||
|
BasicTypeNode(BasicTypes),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 语法分析器节点
|
/// 语法分析器节点
|
||||||
|
@ -104,4 +150,81 @@ impl SyntaxNode {
|
||||||
})
|
})
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn function_call(function: &Rc<RefCell<SyntaxNode>>, arguments: &Vec<Rc<RefCell<SyntaxNode>>>) -> Rc<RefCell<Self>> {
|
||||||
|
Rc::new(RefCell::new(Self {
|
||||||
|
node_type: SyntaxNodeType::FunctionCall(FunctionCallNode {
|
||||||
|
function: Rc::clone(function),
|
||||||
|
arguments: arguments.iter().map(|item| Rc::clone(item)).collect(),
|
||||||
|
})
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn assign_statement(left_value: &Rc<RefCell<SyntaxNode>>, expression: &Rc<RefCell<SyntaxNode>>) -> Rc<RefCell<Self>> {
|
||||||
|
Rc::new(RefCell::new(Self {
|
||||||
|
node_type: SyntaxNodeType::AssignStatement(AssignStatmentNode {
|
||||||
|
left_value: Rc::clone(left_value),
|
||||||
|
expression: Rc::clone(expression),
|
||||||
|
})
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn expression_statement(expression: &Rc<RefCell<SyntaxNode>>) -> Rc<RefCell<SyntaxNode>> {
|
||||||
|
Rc::new(RefCell::new(Self {
|
||||||
|
node_type: SyntaxNodeType::ExpressionStatement(Rc::clone(expression))
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn return_statement(expression: &Rc<RefCell<SyntaxNode>>) -> Rc<RefCell<SyntaxNode>> {
|
||||||
|
Rc::new(RefCell::new(Self {
|
||||||
|
node_type: SyntaxNodeType::ReturnStatement(Rc::clone(expression))
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn unit() -> Rc<RefCell<SyntaxNode>> {
|
||||||
|
Rc::new(RefCell::new(Self {
|
||||||
|
node_type: SyntaxNodeType::Unit
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn break_statement() -> Rc<RefCell<SyntaxNode>> {
|
||||||
|
Rc::new(RefCell::new(Self {
|
||||||
|
node_type: SyntaxNodeType::BreakNode
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn continue_statement() -> Rc<RefCell<SyntaxNode>> {
|
||||||
|
Rc::new(RefCell::new(Self {
|
||||||
|
node_type: SyntaxNodeType::ContinueNode
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn if_statement(condition: &Rc<RefCell<SyntaxNode>>,
|
||||||
|
if_statement: &Rc<RefCell<SyntaxNode>>,
|
||||||
|
else_statement: &Rc<RefCell<SyntaxNode>>) -> Rc<RefCell<SyntaxNode>> {
|
||||||
|
Rc::new(RefCell::new(Self {
|
||||||
|
node_type: SyntaxNodeType::IfStatement(IfStatementNode {
|
||||||
|
condition: Rc::clone(condition),
|
||||||
|
if_statement: Rc::clone(if_statement),
|
||||||
|
else_statement: Rc::clone(else_statement)
|
||||||
|
})
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn while_statement(condition: &Rc<RefCell<SyntaxNode>>, statement: &Rc<RefCell<SyntaxNode>>) -> Rc<RefCell<SyntaxNode>> {
|
||||||
|
Rc::new(RefCell::new(Self {
|
||||||
|
node_type: SyntaxNodeType::WhileStatement(WhileStatmentNode {
|
||||||
|
condition: Rc::clone(condition),
|
||||||
|
statement: Rc::clone(statement)
|
||||||
|
})
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn block(statements: &Vec<Rc<RefCell<SyntaxNode>>>) -> Rc<RefCell<SyntaxNode>> {
|
||||||
|
Rc::new(RefCell::new(Self {
|
||||||
|
node_type: SyntaxNodeType::Block(statements.iter().map(|x| Rc::clone(x)).collect())
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user