add: compiler_unit_parser.
All checks were successful
Run Unit Tests / Run-Unit-Tests (push) Successful in -33s

This commit is contained in:
jackfiled 2024-09-21 15:03:31 +08:00
parent e278a5dcc6
commit 783c5b3e3e
4 changed files with 904 additions and 41 deletions

View File

@ -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)
}

View File

@ -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, &parameters)
},
)(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,
&parameters,
&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);
}
}

View File

@ -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
View 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;
}");
}