add: compiler_unit_parser.
All checks were successful
Run Unit Tests / Run-Unit-Tests (push) Successful in -33s
All checks were successful
Run Unit Tests / Run-Unit-Tests (push) Successful in -33s
This commit is contained in:
parent
e278a5dcc6
commit
783c5b3e3e
|
@ -1,3 +1,24 @@
|
|||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
use nom::branch::alt;
|
||||
use nom::combinator::map;
|
||||
use nom::IResult;
|
||||
use nom::multi::many1;
|
||||
use crate::parser::grammar_parser::{function_declaration_parser, value_declaration_parser};
|
||||
use crate::parser::syntax_tree::SyntaxNode;
|
||||
use crate::tokenizer::LexicalTokenSpan;
|
||||
|
||||
mod syntax_tree;
|
||||
mod grammar_parser;
|
||||
|
||||
pub fn compiler_unit_parser(cursor: LexicalTokenSpan) -> IResult<LexicalTokenSpan, Rc<RefCell<SyntaxNode>>> {
|
||||
map(
|
||||
many1(alt((
|
||||
value_declaration_parser,
|
||||
function_declaration_parser
|
||||
))),
|
||||
|blocks| {
|
||||
SyntaxNode::block(&blocks)
|
||||
}
|
||||
)(cursor)
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
use crate::parser::syntax_tree::{BinaryNodeType, SyntaxNode, UnaryNodeType};
|
||||
use crate::parser::syntax_tree::{BasicTypes, BinaryNodeType, InitializerNode, SyntaxNode, UnaryNodeType};
|
||||
use crate::tokenizer::{LexicalTokenSpan, LexicalTokenType};
|
||||
use nom::branch::alt;
|
||||
use nom::combinator::{map, opt};
|
||||
use nom::multi::{many0, separated_list0};
|
||||
use nom::multi::{many0, separated_list0, separated_list1};
|
||||
use nom::sequence::tuple;
|
||||
use nom::IResult;
|
||||
use std::cell::RefCell;
|
||||
|
@ -510,6 +510,7 @@ fn block_parser(cursor: LexicalTokenSpan) -> IResult<LexicalTokenSpan, Rc<RefCel
|
|||
tuple((
|
||||
lexical!(Delimiter("{")),
|
||||
many0(alt((
|
||||
value_declaration_parser,
|
||||
statement_parser,
|
||||
))),
|
||||
lexical!(Delimiter("}"))
|
||||
|
@ -520,6 +521,189 @@ fn block_parser(cursor: LexicalTokenSpan) -> IResult<LexicalTokenSpan, Rc<RefCel
|
|||
)(cursor)
|
||||
}
|
||||
|
||||
fn value_initializer_parser(cursor: LexicalTokenSpan) -> IResult<LexicalTokenSpan, Rc<RefCell<InitializerNode>>> {
|
||||
alt((
|
||||
map(
|
||||
tuple((
|
||||
lexical!(Delimiter("{")),
|
||||
separated_list0(lexical!(Delimiter(",")), value_initializer_parser),
|
||||
lexical!(Delimiter("}"))
|
||||
)),
|
||||
|(_, initializers, _)| {
|
||||
InitializerNode::array(initializers)
|
||||
},
|
||||
),
|
||||
map(
|
||||
expression_parser,
|
||||
|expression| {
|
||||
InitializerNode::single(expression)
|
||||
},
|
||||
)
|
||||
))(cursor)
|
||||
}
|
||||
|
||||
type ValueDefinitionParseType<'a> = (Rc<RefCell<SyntaxNode>>, Vec<(LexicalTokenSpan<'a>, Rc<RefCell<SyntaxNode>>, LexicalTokenSpan<'a>)>);
|
||||
|
||||
type InitializedValueDefinitionParseType<'a> = (Rc<RefCell<SyntaxNode>>, Vec<(LexicalTokenSpan<'a>, Rc<RefCell<SyntaxNode>>,
|
||||
LexicalTokenSpan<'a>)>, LexicalTokenSpan<'a>, Rc<RefCell<InitializerNode>>);
|
||||
fn value_definition_parser(cursor: LexicalTokenSpan) -> IResult<LexicalTokenSpan, Rc<RefCell<SyntaxNode>>> {
|
||||
alt((
|
||||
map(
|
||||
tuple((
|
||||
identifier_parser,
|
||||
many0(
|
||||
tuple((
|
||||
lexical!(Delimiter("[")),
|
||||
expression_parser,
|
||||
lexical!(Delimiter("]"))
|
||||
))
|
||||
),
|
||||
lexical!(Operator("=")),
|
||||
value_initializer_parser
|
||||
)),
|
||||
|(identifier, indexers, _, initializer): InitializedValueDefinitionParseType| {
|
||||
SyntaxNode::initialized_value_definition(
|
||||
&identifier,
|
||||
indexers.iter().map(|p| &p.1),
|
||||
&initializer,
|
||||
)
|
||||
},
|
||||
),
|
||||
map(tuple((
|
||||
identifier_parser,
|
||||
many0(tuple((
|
||||
lexical!(Delimiter("[")),
|
||||
expression_parser,
|
||||
lexical!(Delimiter("]"))
|
||||
)))
|
||||
)),
|
||||
|(identifier, indexers): ValueDefinitionParseType| {
|
||||
SyntaxNode::value_definition(
|
||||
&identifier,
|
||||
indexers.iter().map(|p| &p.1),
|
||||
)
|
||||
},
|
||||
)
|
||||
))(cursor)
|
||||
}
|
||||
|
||||
fn basic_type_parser(cursor: LexicalTokenSpan) -> IResult<LexicalTokenSpan, BasicTypes> {
|
||||
alt((
|
||||
map(
|
||||
lexical!(Keyword("void")),
|
||||
|_| {
|
||||
BasicTypes::Void
|
||||
},
|
||||
),
|
||||
map(
|
||||
lexical!(Keyword("int")),
|
||||
|_| {
|
||||
BasicTypes::Integer
|
||||
},
|
||||
),
|
||||
map(
|
||||
lexical!(Keyword("float")),
|
||||
|_| {
|
||||
BasicTypes::Float
|
||||
},
|
||||
)
|
||||
))(cursor)
|
||||
}
|
||||
|
||||
pub fn value_declaration_parser(cursor: LexicalTokenSpan) -> IResult<LexicalTokenSpan, Rc<RefCell<SyntaxNode>>> {
|
||||
alt((
|
||||
map(
|
||||
tuple((
|
||||
lexical!(Keyword("const")),
|
||||
basic_type_parser,
|
||||
separated_list1(lexical!(Delimiter(",")), value_definition_parser),
|
||||
lexical!(Delimiter(";"))
|
||||
)),
|
||||
|(_, basic_type, definitions, _)| {
|
||||
SyntaxNode::value_declaration(
|
||||
true,
|
||||
basic_type,
|
||||
&definitions,
|
||||
)
|
||||
},
|
||||
),
|
||||
map(
|
||||
tuple((
|
||||
basic_type_parser,
|
||||
separated_list1(lexical!(Delimiter(",")), value_definition_parser),
|
||||
lexical!(Delimiter(";"))
|
||||
)),
|
||||
|(basic_type, definitions, _)| {
|
||||
SyntaxNode::value_declaration(
|
||||
false,
|
||||
basic_type,
|
||||
&definitions,
|
||||
)
|
||||
},
|
||||
)
|
||||
))(cursor)
|
||||
}
|
||||
|
||||
type FunctionParameterParseResult<'a> = (BasicTypes,
|
||||
Rc<RefCell<SyntaxNode>>,
|
||||
Option<(LexicalTokenSpan<'a>,
|
||||
LexicalTokenSpan<'a>,
|
||||
Vec<(LexicalTokenSpan<'a>, Rc<RefCell<SyntaxNode>>, LexicalTokenSpan<'a>)>)>);
|
||||
fn function_parameter_parser(cursor: LexicalTokenSpan) -> IResult<LexicalTokenSpan, Rc<RefCell<SyntaxNode>>> {
|
||||
map(
|
||||
tuple((
|
||||
basic_type_parser,
|
||||
identifier_parser,
|
||||
opt(tuple((
|
||||
lexical!(Delimiter("[")),
|
||||
lexical!(Delimiter("]")),
|
||||
many0(tuple((
|
||||
lexical!(Delimiter("[")),
|
||||
expression_parser,
|
||||
lexical!(Delimiter("]")),
|
||||
)))
|
||||
)))
|
||||
)),
|
||||
|(basic_type, identifier, indexers): FunctionParameterParseResult| {
|
||||
let parameters = if let Some(indexers) = indexers {
|
||||
let mut result = vec![SyntaxNode::unit()];
|
||||
|
||||
for indexer in indexers.2 {
|
||||
result.push(Rc::clone(&indexer.1));
|
||||
}
|
||||
|
||||
result
|
||||
} else {
|
||||
vec![]
|
||||
};
|
||||
|
||||
SyntaxNode::function_parameter(basic_type, &identifier, ¶meters)
|
||||
},
|
||||
)(cursor)
|
||||
}
|
||||
|
||||
|
||||
pub fn function_declaration_parser(cursor: LexicalTokenSpan) -> IResult<LexicalTokenSpan, Rc<RefCell<SyntaxNode>>> {
|
||||
map(
|
||||
tuple((
|
||||
basic_type_parser,
|
||||
identifier_parser,
|
||||
lexical!(Delimiter("(")),
|
||||
separated_list0(lexical!(Delimiter(",")), function_parameter_parser),
|
||||
lexical!(Delimiter(")")),
|
||||
block_parser
|
||||
)),
|
||||
|(basic_type, identifier, _, parameters, _, block)| {
|
||||
SyntaxNode::function_declaration(
|
||||
basic_type,
|
||||
&identifier,
|
||||
¶meters,
|
||||
&block,
|
||||
)
|
||||
},
|
||||
)(cursor)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
@ -801,7 +985,7 @@ mod test {
|
|||
&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);
|
||||
|
||||
|
@ -810,13 +994,13 @@ mod test {
|
|||
&SyntaxNode::identifier("i".to_owned()), &SyntaxNode::const_integer(1)),
|
||||
&SyntaxNode::assign_statement(&SyntaxNode::identifier("i".to_owned()),
|
||||
&SyntaxNode::const_integer(2)),
|
||||
&SyntaxNode::unit()
|
||||
&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(
|
||||
|
@ -824,33 +1008,33 @@ mod test {
|
|||
&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::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::const_integer(1)),
|
||||
),
|
||||
&SyntaxNode::unit()
|
||||
&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::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))
|
||||
)
|
||||
&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);
|
||||
}
|
||||
|
@ -870,23 +1054,152 @@ mod test {
|
|||
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))
|
||||
&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);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn value_initializer_test() {
|
||||
let initializer = InitializerNode::single(SyntaxNode::const_integer(1));
|
||||
let (_, tokens) = lexical_parser("1").unwrap();
|
||||
let (_, node) = value_initializer_parser((&tokens).into()).unwrap();
|
||||
assert_eq!(initializer, node);
|
||||
|
||||
let initializer = InitializerNode::array(vec![InitializerNode::single(SyntaxNode::const_integer(1)),
|
||||
InitializerNode::single(SyntaxNode::const_integer(2))]);
|
||||
let (_, tokens) = lexical_parser("{1, 2}").unwrap();
|
||||
let (_, node) = value_initializer_parser((&tokens).into()).unwrap();
|
||||
assert_eq!(initializer, node);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn value_definition_test() {
|
||||
let node = SyntaxNode::initialized_value_definition(
|
||||
&SyntaxNode::identifier("i".to_owned()),
|
||||
vec![],
|
||||
&InitializerNode::single(SyntaxNode::const_integer(1)),
|
||||
);
|
||||
validate_syntax_node("i = 1", &node.borrow().node_type, value_definition_parser);
|
||||
|
||||
let node = SyntaxNode::value_definition(
|
||||
&SyntaxNode::identifier("array".to_owned()),
|
||||
vec![
|
||||
SyntaxNode::const_integer(100),
|
||||
SyntaxNode::const_integer(10)
|
||||
].iter(),
|
||||
);
|
||||
validate_syntax_node("array[100][10]", &node.borrow().node_type, value_definition_parser);
|
||||
|
||||
let node = SyntaxNode::initialized_value_definition(
|
||||
&SyntaxNode::identifier("test".to_owned()),
|
||||
vec![
|
||||
SyntaxNode::const_integer(3)
|
||||
].iter(),
|
||||
&InitializerNode::array(vec![
|
||||
InitializerNode::single(SyntaxNode::const_integer(1)),
|
||||
InitializerNode::single(SyntaxNode::const_integer(2)),
|
||||
InitializerNode::single(SyntaxNode::const_integer(3)),
|
||||
]),
|
||||
);
|
||||
validate_syntax_node("test[3] = {1,2,3}", &node.borrow().node_type, value_definition_parser);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn value_declaration_test() {
|
||||
let node1 = SyntaxNode::initialized_value_definition(
|
||||
&SyntaxNode::identifier("i".to_owned()),
|
||||
vec![],
|
||||
&InitializerNode::single(SyntaxNode::const_integer(1)),
|
||||
);
|
||||
let node2 = SyntaxNode::value_definition(
|
||||
&SyntaxNode::identifier("array".to_owned()),
|
||||
vec![
|
||||
SyntaxNode::const_integer(100),
|
||||
SyntaxNode::const_integer(10)
|
||||
].iter(),
|
||||
);
|
||||
let node = SyntaxNode::value_declaration(
|
||||
false,
|
||||
BasicTypes::Integer,
|
||||
&vec![node1, node2],
|
||||
);
|
||||
validate_syntax_node("int i = 1, array[100][10];", &node.borrow().node_type, value_declaration_parser);
|
||||
|
||||
|
||||
let node = SyntaxNode::initialized_value_definition(
|
||||
&SyntaxNode::identifier("test".to_owned()),
|
||||
vec![
|
||||
SyntaxNode::const_integer(3)
|
||||
].iter(),
|
||||
&InitializerNode::array(vec![
|
||||
InitializerNode::single(SyntaxNode::const_float(1f32)),
|
||||
InitializerNode::single(SyntaxNode::const_float(2f32)),
|
||||
InitializerNode::single(SyntaxNode::const_float(3f32)),
|
||||
]),
|
||||
);
|
||||
let node = SyntaxNode::value_declaration(
|
||||
true,
|
||||
BasicTypes::Float,
|
||||
&vec![node],
|
||||
);
|
||||
validate_syntax_node("const float test[3] = {1.0,2.0,3.0};", &node.borrow().node_type, value_declaration_parser);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn function_parameter_test() {
|
||||
let node = SyntaxNode::function_parameter(BasicTypes::Integer,
|
||||
&SyntaxNode::identifier("a".to_owned()), &vec![]);
|
||||
validate_syntax_node("int a", &node.borrow().node_type, function_parameter_parser);
|
||||
|
||||
let node = SyntaxNode::function_parameter(BasicTypes::Float,
|
||||
&SyntaxNode::identifier("array".to_owned()), &vec![SyntaxNode::unit()]);
|
||||
validate_syntax_node("float array[]", &node.borrow().node_type, function_parameter_parser);
|
||||
|
||||
let node = SyntaxNode::function_parameter(BasicTypes::Integer,
|
||||
&SyntaxNode::identifier("array".to_owned()),
|
||||
&vec![SyntaxNode::unit(), SyntaxNode::const_integer(10)]);
|
||||
validate_syntax_node("int array[][10]", &node.borrow().node_type, function_parameter_parser);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn function_declaration_test() {
|
||||
let node = SyntaxNode::function_declaration(
|
||||
BasicTypes::Void,
|
||||
&SyntaxNode::identifier("test".to_owned()),
|
||||
&vec![],
|
||||
&SyntaxNode::block(&vec![
|
||||
SyntaxNode::assign_statement(&SyntaxNode::identifier("a".to_owned()), &SyntaxNode::const_integer(1))
|
||||
]),
|
||||
);
|
||||
validate_syntax_node("void test()\
|
||||
{\
|
||||
a = 1;\
|
||||
}", &node.borrow().node_type, function_declaration_parser);
|
||||
|
||||
let node = SyntaxNode::function_declaration(
|
||||
BasicTypes::Integer,
|
||||
&SyntaxNode::identifier("empty".to_owned()),
|
||||
&vec![
|
||||
SyntaxNode::function_parameter(BasicTypes::Integer, &SyntaxNode::identifier("a".to_owned()), &vec![])
|
||||
],
|
||||
&SyntaxNode::block(&vec![])
|
||||
);
|
||||
validate_syntax_node("int empty(int a) {}", &node.borrow().node_type, function_declaration_parser);
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
use nom::IResult;
|
||||
use crate::parser::syntax_tree::SyntaxNodeType::FunctionParameter;
|
||||
|
||||
/// 单元表达式类型
|
||||
#[derive(Debug, PartialEq)]
|
||||
|
@ -50,13 +50,6 @@ pub struct FunctionCallNode {
|
|||
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>>,
|
||||
|
@ -76,6 +69,58 @@ pub struct AssignStatmentNode {
|
|||
pub expression: Rc<RefCell<SyntaxNode>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum BasicTypes {
|
||||
Void,
|
||||
Integer,
|
||||
Float,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum InitializerNode {
|
||||
Single(Rc<RefCell<SyntaxNode>>),
|
||||
Array(Vec<Rc<RefCell<InitializerNode>>>),
|
||||
}
|
||||
|
||||
impl InitializerNode {
|
||||
pub fn single(node: Rc<RefCell<SyntaxNode>>) -> Rc<RefCell<Self>> {
|
||||
Rc::new(RefCell::new(Self::Single(node)))
|
||||
}
|
||||
|
||||
pub fn array(nodes: Vec<Rc<RefCell<InitializerNode>>>) -> Rc<RefCell<Self>> {
|
||||
Rc::new(RefCell::new(Self::Array(nodes)))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct ValueDefinitionNode {
|
||||
pub identifier: Rc<RefCell<SyntaxNode>>,
|
||||
pub indexers: Vec<Rc<RefCell<SyntaxNode>>>,
|
||||
pub initialzier: Option<Rc<RefCell<InitializerNode>>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct ValueDeclarationNode {
|
||||
pub is_constant: bool,
|
||||
pub value_type: BasicTypes,
|
||||
pub definitions: Vec<Rc<RefCell<SyntaxNode>>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct FunctionParameterNode {
|
||||
pub parameter_type: BasicTypes,
|
||||
pub identifier: Rc<RefCell<SyntaxNode>>,
|
||||
pub indexers: Vec<Rc<RefCell<SyntaxNode>>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct FunctionDeclarationNode {
|
||||
pub function_type: BasicTypes,
|
||||
pub identifier: Rc<RefCell<SyntaxNode>>,
|
||||
pub parameters: Vec<Rc<RefCell<SyntaxNode>>>,
|
||||
pub block: Rc<RefCell<SyntaxNode>>,
|
||||
}
|
||||
|
||||
/// 语法分析树节点类型
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum SyntaxNodeType {
|
||||
|
@ -96,7 +141,10 @@ pub enum SyntaxNodeType {
|
|||
ExpressionStatement(Rc<RefCell<SyntaxNode>>),
|
||||
ReturnStatement(Rc<RefCell<SyntaxNode>>),
|
||||
Block(Vec<Rc<RefCell<SyntaxNode>>>),
|
||||
BasicTypeNode(BasicTypes),
|
||||
ValueDefinition(ValueDefinitionNode),
|
||||
ValueDeclaration(ValueDeclarationNode),
|
||||
FunctionParameter(FunctionParameterNode),
|
||||
FunctionDeclaration(FunctionDeclarationNode),
|
||||
}
|
||||
|
||||
/// 语法分析器节点
|
||||
|
@ -180,7 +228,7 @@ impl SyntaxNode {
|
|||
node_type: SyntaxNodeType::ReturnStatement(Rc::clone(expression))
|
||||
}))
|
||||
}
|
||||
|
||||
|
||||
pub fn unit() -> Rc<RefCell<SyntaxNode>> {
|
||||
Rc::new(RefCell::new(Self {
|
||||
node_type: SyntaxNodeType::Unit
|
||||
|
@ -192,39 +240,101 @@ impl SyntaxNode {
|
|||
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>>,
|
||||
|
||||
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)
|
||||
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)
|
||||
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())
|
||||
}))
|
||||
}
|
||||
|
||||
|
||||
|
||||
pub fn value_definition<'a, T>(identifier: &Rc<RefCell<SyntaxNode>>, indexers: T) -> Rc<RefCell<Self>>
|
||||
where
|
||||
T: IntoIterator<Item=&'a Rc<RefCell<SyntaxNode>>>,
|
||||
{
|
||||
Rc::new(RefCell::new(Self {
|
||||
node_type: SyntaxNodeType::ValueDefinition(ValueDefinitionNode {
|
||||
identifier: Rc::clone(identifier),
|
||||
indexers: indexers.into_iter().map(|x| Rc::clone(x)).collect(),
|
||||
initialzier: None,
|
||||
})
|
||||
}))
|
||||
}
|
||||
|
||||
pub fn initialized_value_definition<'a, T>(identifier: &Rc<RefCell<SyntaxNode>>,
|
||||
indexers: T,
|
||||
initializer: &Rc<RefCell<InitializerNode>>) -> Rc<RefCell<Self>>
|
||||
where
|
||||
T: IntoIterator<Item=&'a Rc<RefCell<SyntaxNode>>>,
|
||||
{
|
||||
Rc::new(RefCell::new(Self {
|
||||
node_type: SyntaxNodeType::ValueDefinition(ValueDefinitionNode {
|
||||
identifier: Rc::clone(identifier),
|
||||
indexers: indexers.into_iter().map(|x| Rc::clone(x)).collect(),
|
||||
initialzier: Some(Rc::clone(initializer)),
|
||||
})
|
||||
}))
|
||||
}
|
||||
|
||||
pub fn value_declaration(is_constant: bool, value_type: BasicTypes, definitions: &Vec<Rc<RefCell<SyntaxNode>>>) -> Rc<RefCell<SyntaxNode>> {
|
||||
Rc::new(RefCell::new(Self {
|
||||
node_type: SyntaxNodeType::ValueDeclaration(ValueDeclarationNode {
|
||||
is_constant,
|
||||
value_type,
|
||||
definitions: definitions.iter().map(|x| Rc::clone(x)).collect(),
|
||||
})
|
||||
}))
|
||||
}
|
||||
|
||||
pub fn function_parameter(parameter_type: BasicTypes,
|
||||
identifier: &Rc<RefCell<SyntaxNode>>,
|
||||
indexers: &Vec<Rc<RefCell<SyntaxNode>>>) -> Rc<RefCell<SyntaxNode>> {
|
||||
Rc::new(RefCell::new(Self {
|
||||
node_type: FunctionParameter(FunctionParameterNode {
|
||||
parameter_type,
|
||||
identifier: Rc::clone(identifier),
|
||||
indexers: indexers.iter().map(|x| Rc::clone(x)).collect(),
|
||||
})
|
||||
}))
|
||||
}
|
||||
|
||||
pub fn function_declaration(function_type: BasicTypes,
|
||||
identifier: &Rc<RefCell<SyntaxNode>>,
|
||||
parameters: &Vec<Rc<RefCell<SyntaxNode>>>,
|
||||
block: &Rc<RefCell<SyntaxNode>>) -> Rc<RefCell<Self>> {
|
||||
Rc::new(RefCell::new(Self {
|
||||
node_type: SyntaxNodeType::FunctionDeclaration(FunctionDeclarationNode {
|
||||
function_type,
|
||||
identifier: Rc::clone(identifier),
|
||||
parameters: parameters.iter().map(|x| Rc::clone(x)).collect(),
|
||||
block: Rc::clone(block),
|
||||
})
|
||||
}))
|
||||
}
|
||||
}
|
419
tests/grammar_tests.rs
Normal file
419
tests/grammar_tests.rs
Normal file
|
@ -0,0 +1,419 @@
|
|||
use nom::InputLength;
|
||||
use rustic_sysy::parser::compiler_unit_parser;
|
||||
use rustic_sysy::tokenizer::lexical_parser;
|
||||
|
||||
fn parse_grammar(input: &'static str) {
|
||||
let (_, tokens) = lexical_parser(input).unwrap();
|
||||
let (remaining, node) = compiler_unit_parser((&tokens).into()).unwrap();
|
||||
dbg!(node);
|
||||
|
||||
assert_eq!(0, remaining.input_len());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn main_test() {
|
||||
parse_grammar(r"int main(){
|
||||
return 3;
|
||||
}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn value_definition_test() {
|
||||
parse_grammar(r"//test domain of global var define and local define
|
||||
int a = 3;
|
||||
int b = 5;
|
||||
|
||||
int main(){
|
||||
int a = 5;
|
||||
return a + b;
|
||||
}");
|
||||
|
||||
parse_grammar(r"//test local var define
|
||||
int main(){
|
||||
int a, b0, _c;
|
||||
a = 1;
|
||||
b0 = 2;
|
||||
_c = 3;
|
||||
return b0 + _c;
|
||||
}");
|
||||
|
||||
parse_grammar(r"//test const gloal var define
|
||||
const int a = 10, b = 5;
|
||||
|
||||
int main(){
|
||||
return b;
|
||||
}");
|
||||
|
||||
parse_grammar(r"//test const local var define
|
||||
int main(){
|
||||
const int a = 10, b = 5;
|
||||
return b;
|
||||
}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn array_definition_test() {
|
||||
parse_grammar(r"int a[10][10];
|
||||
int main(){
|
||||
return 0;
|
||||
}");
|
||||
|
||||
parse_grammar(r"//test array define
|
||||
int main(){
|
||||
int a[4][2] = {};
|
||||
int b[4][2] = {1, 2, 3, 4, 5, 6, 7, 8};
|
||||
int c[4][2] = {{1, 2}, {3, 4}, {5, 6}, {7, 8}};
|
||||
int d[4][2] = {1, 2, {3}, {5}, 7 , 8};
|
||||
int e[4][2] = {{d[2][1], c[2][1]}, {3, 4}, {5, 6}, {7, 8}};
|
||||
return e[3][1] + e[0][0] + e[0][1] + a[2][0];
|
||||
}");
|
||||
|
||||
parse_grammar(r"int main(){
|
||||
const int a[4][2] = {{1, 2}, {3, 4}, {}, 7};
|
||||
const int N = 3;
|
||||
int b[4][2] = {};
|
||||
int c[4][2] = {1, 2, 3, 4, 5, 6, 7, 8};
|
||||
int d[N + 1][2] = {1, 2, {3}, {5}, a[3][0], 8};
|
||||
int e[4][2][1] = {{d[2][1], {c[2][1]}}, {3, 4}, {5, 6}, {7, 8}};
|
||||
return e[3][1][0] + e[0][0][0] + e[0][1][0] + d[3][0];
|
||||
}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn operator_priority_test() {
|
||||
parse_grammar(r"//test the priority of add and mul
|
||||
int main(){
|
||||
int a, b, c, d;
|
||||
a = 10;
|
||||
b = 4;
|
||||
c = 2;
|
||||
d = 2;
|
||||
return c + a * b - d;
|
||||
}");
|
||||
|
||||
parse_grammar(r"//test the priority of add and mul
|
||||
int main(){
|
||||
int a, b, c, d;
|
||||
a = 10;
|
||||
b = 4;
|
||||
c = 2;
|
||||
d = 2;
|
||||
return (c + a) * (b - d);
|
||||
}");
|
||||
|
||||
parse_grammar(r"//test the priority of unary operator and binary operator
|
||||
int main(){
|
||||
int a, b;
|
||||
a = 10;
|
||||
b = 30;
|
||||
return a - -5 + b + -5;
|
||||
}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn statement_test() {
|
||||
parse_grammar(r"int k;
|
||||
const int n = 10;
|
||||
int main () {
|
||||
int i = 0;
|
||||
k = 1;
|
||||
while (i <= n - 1) {
|
||||
i = i + 1;
|
||||
k + 1;
|
||||
k = k + k;
|
||||
}
|
||||
putint(k);
|
||||
return k;
|
||||
}");
|
||||
|
||||
parse_grammar(r"// test if-else-if
|
||||
int ifElseIf() {
|
||||
int a;
|
||||
a = 5;
|
||||
int b;
|
||||
b = 10;
|
||||
if(a == 6 || b == 0xb) {
|
||||
return a;
|
||||
}
|
||||
else {
|
||||
if (b == 10 && a == 1)
|
||||
a = 25;
|
||||
else if (b == 10 && a == -5)
|
||||
a = a + 15;
|
||||
else
|
||||
a = -+a;
|
||||
}
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
int main(){
|
||||
putint(ifElseIf());
|
||||
return 0;
|
||||
}");
|
||||
|
||||
parse_grammar(r"// test if-if-else
|
||||
int ififElse() {
|
||||
int a;
|
||||
a = 5;
|
||||
int b;
|
||||
b = 10;
|
||||
if(a == 5)
|
||||
if (b == 10)
|
||||
a = 25;
|
||||
else
|
||||
a = a + 15;
|
||||
|
||||
return (a);
|
||||
}
|
||||
|
||||
int main(){
|
||||
return (ififElse());
|
||||
}");
|
||||
|
||||
parse_grammar(r"// test if-{if-else}
|
||||
int if_ifElse_() {
|
||||
int a;
|
||||
a = 5;
|
||||
int b;
|
||||
b = 10;
|
||||
if(a == 5){
|
||||
if (b == 10)
|
||||
a = 25;
|
||||
else
|
||||
a = a + 15;
|
||||
}
|
||||
return (a);
|
||||
}
|
||||
|
||||
int main(){
|
||||
return (if_ifElse_());
|
||||
}");
|
||||
|
||||
parse_grammar(r"// test while-if
|
||||
int whileIf() {
|
||||
int a;
|
||||
a = 0;
|
||||
int b;
|
||||
b = 0;
|
||||
while (a < 100) {
|
||||
if (a == 5) {
|
||||
b = 25;
|
||||
}
|
||||
else if (a == 10) {
|
||||
b = 42;
|
||||
}
|
||||
else {
|
||||
b = a * 2;
|
||||
}
|
||||
a = a + 1;
|
||||
}
|
||||
return (b);
|
||||
}
|
||||
|
||||
|
||||
int main(){
|
||||
return (whileIf());
|
||||
}");
|
||||
|
||||
parse_grammar(r"int deepWhileBr(int a, int b) {
|
||||
int c;
|
||||
c = a + b;
|
||||
while (c < 75) {
|
||||
int d;
|
||||
d = 42;
|
||||
if (c < 100) {
|
||||
c = c + d;
|
||||
if (c > 99) {
|
||||
int e;
|
||||
e = d * 2;
|
||||
if (1 == 1) {
|
||||
c = e * 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return (c);
|
||||
}
|
||||
|
||||
int main() {
|
||||
int p;
|
||||
p = 2;
|
||||
return deepWhileBr(p, p);
|
||||
}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dijkstra_test() {
|
||||
parse_grammar(r"const int INF = 65535;
|
||||
int e[16][16];
|
||||
int book[16];
|
||||
int dis[16];
|
||||
int n, m;
|
||||
int v1, v2, w;
|
||||
|
||||
void Dijkstra()
|
||||
{
|
||||
int i, j;
|
||||
|
||||
i = 1;
|
||||
while (i <= n) {
|
||||
dis[i] = e[1][i];
|
||||
book[i] = 0;
|
||||
i = i + 1;
|
||||
}
|
||||
book[1] = 1;
|
||||
|
||||
i = 1;
|
||||
while (i <= n - 1) {
|
||||
int min_num = INF;
|
||||
int min_index = 0;
|
||||
int k = 1;
|
||||
while (k <= n) {
|
||||
if (min_num > dis[k] && book[k] == 0) {
|
||||
min_num = dis[k];
|
||||
min_index = k;
|
||||
}
|
||||
k = k + 1;
|
||||
}
|
||||
book[min_index] = 1;
|
||||
int j = 1;
|
||||
while (j <= n) {
|
||||
if (e[min_index][j] < INF) {
|
||||
if (dis[j] > dis[min_index] + e[min_index][j]) {
|
||||
dis[j] = dis[min_index] + e[min_index][j];
|
||||
}
|
||||
}
|
||||
j = j + 1;
|
||||
}
|
||||
i = i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int i;
|
||||
n = getint();
|
||||
m = getint();
|
||||
|
||||
i = 1;
|
||||
while (i <= n) {
|
||||
int j = 1;
|
||||
while (j <= n) {
|
||||
if (i == j)
|
||||
e[i][j] = 0;
|
||||
else
|
||||
e[i][j] = INF;
|
||||
j = j + 1;
|
||||
}
|
||||
i = i + 1;
|
||||
}
|
||||
|
||||
i = 1;
|
||||
while (i <= m) {
|
||||
int u = getint(), v = getint();
|
||||
e[u][v] = getint();
|
||||
i = i + 1;
|
||||
}
|
||||
|
||||
Dijkstra();
|
||||
|
||||
i = 1;
|
||||
while (i <= n) {
|
||||
putint(dis[i]);
|
||||
putch(32);
|
||||
i = i + 1;
|
||||
}
|
||||
putch(10);
|
||||
return 0;
|
||||
}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sort_test() {
|
||||
parse_grammar(r"int n;
|
||||
int bubblesort(int arr[])
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
i =0;
|
||||
while(i < n-1){
|
||||
// Last i elements are already in place
|
||||
j = 0;
|
||||
while(j < n-i-1){
|
||||
if (arr[j] > arr[j+1]) {
|
||||
// swap(&arr[j], &arr[j+1]);
|
||||
int tmp;
|
||||
tmp = arr[j+1];
|
||||
arr[j+1] = arr[j];
|
||||
arr[j] = tmp;
|
||||
}
|
||||
j = j + 1;
|
||||
}
|
||||
i = i + 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(){
|
||||
n = 10;
|
||||
int a[10];
|
||||
a[0]=4;a[1]=3;a[2]=9;a[3]=2;a[4]=0;
|
||||
a[5]=1;a[6]=6;a[7]=5;a[8]=7;a[9]=8;
|
||||
int i;
|
||||
i = bubblesort(a);
|
||||
while (i < n) {
|
||||
int tmp;
|
||||
tmp = a[i];
|
||||
putint(tmp);
|
||||
tmp = 10;
|
||||
putch(tmp);
|
||||
i = i + 1;
|
||||
}
|
||||
return 0;
|
||||
}");
|
||||
|
||||
parse_grammar(r"int n;
|
||||
int insertsort(int a[])
|
||||
{
|
||||
int i;
|
||||
i = 1;
|
||||
while(i<n)
|
||||
{
|
||||
int temp;
|
||||
temp=a[i];
|
||||
int j;
|
||||
j=i-1;
|
||||
while(j>-1&&temp<a[j])
|
||||
{
|
||||
a[j+1]=a[j];
|
||||
j = j - 1;
|
||||
}
|
||||
a[j+1]=temp;
|
||||
i = i + 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(){
|
||||
n = 10;
|
||||
int a[10];
|
||||
a[0]=4;a[1]=3;a[2]=9;a[3]=2;a[4]=0;
|
||||
a[5]=1;a[6]=6;a[7]=5;a[8]=7;a[9]=8;
|
||||
int i;
|
||||
i = insertsort(a);
|
||||
while (i < n) {
|
||||
int tmp;
|
||||
tmp = a[i];
|
||||
putint(tmp);
|
||||
tmp = 10;
|
||||
putch(tmp);
|
||||
i = i + 1;
|
||||
}
|
||||
return 0;
|
||||
}");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user