From 25b5d78c428c501551045c1de1f9a95a562b9c79 Mon Sep 17 00:00:00 2001 From: cjw Date: Wed, 21 Dec 2022 21:33:26 +0800 Subject: [PATCH 1/4] fix: catch err when missing space --- src/nomparser/array.rs | 10 +++++----- src/nomparser/constval.rs | 14 +++++++------- src/nomparser/control.rs | 20 ++++++++++---------- src/nomparser/expression.rs | 15 +++++++++------ src/nomparser/function.rs | 16 ++++++++-------- src/nomparser/helper.rs | 19 ++++++++++++++++++- src/nomparser/identifier.rs | 11 +++++++---- src/nomparser/implement.rs | 8 ++++---- src/nomparser/macros.rs | 4 ++-- src/nomparser/pkg.rs | 8 ++++---- src/nomparser/statement.rs | 22 +++++++++++----------- src/nomparser/string_literal.rs | 4 ++-- src/nomparser/structure.rs | 16 ++++++++-------- src/nomparser/types.rs | 28 ++++++++++++++-------------- 14 files changed, 109 insertions(+), 86 deletions(-) diff --git a/src/nomparser/array.rs b/src/nomparser/array.rs index ace2414f1..1c3472924 100644 --- a/src/nomparser/array.rs +++ b/src/nomparser/array.rs @@ -21,12 +21,12 @@ use super::*; pub fn array_init(input: Span) -> IResult> { map_res( tuple(( - tag_token(TokenType::LBRACKET), + tag_token_symbol(TokenType::LBRACKET), separated_list0( - tag_token(TokenType::COMMA), + tag_token_symbol(TokenType::COMMA), del_newline_or_space!(logic_exp), ), - tag_token(TokenType::RBRACKET), + tag_token_symbol(TokenType::RBRACKET), )), |((_, lb), exps, (_, rb))| { let range = lb.start.to(rb.end); @@ -41,9 +41,9 @@ pub fn array_init(input: Span) -> IResult> { pub fn array_element_op(input: Span) -> IResult>)> { delspace(map_res( tuple(( - tag_token(TokenType::LBRACKET), + tag_token_symbol(TokenType::LBRACKET), opt(logic_exp), - tag_token(TokenType::RBRACKET), + tag_token_symbol(TokenType::RBRACKET), many0(comment), )), |(_, idx, (_, rr), com)| { diff --git a/src/nomparser/constval.rs b/src/nomparser/constval.rs index 81351d853..511b37cfb 100644 --- a/src/nomparser/constval.rs +++ b/src/nomparser/constval.rs @@ -36,16 +36,16 @@ pub fn number(input: Span) -> IResult> { Ok((re, Box::new(node.into()))) } -#[test_parser("true")] +#[test_parser(" true")] #[test_parser("false")] #[test_parser_error("tru")] #[test_parser_error("fales")] pub fn bool_const(input: Span) -> IResult> { alt(( - map_res(tag_token(TokenType::TRUE), |(_, range)| { + map_res(tag_token_word(TokenType::TRUE), |(_, range)| { res_enum(BoolConstNode { value: true, range }.into()) }), - map_res(tag_token(TokenType::FALSE), |(_, range)| { + map_res(tag_token_word(TokenType::FALSE), |(_, range)| { res_enum( BoolConstNode { value: false, @@ -70,8 +70,8 @@ fn float(input: Span) -> IResult { opt(tuple(( one_of("eE"), opt(alt(( - tag_token(TokenType::PLUS), - tag_token(TokenType::MINUS), + tag_token_symbol(TokenType::PLUS), + tag_token_symbol(TokenType::MINUS), ))), decimal, ))), @@ -81,8 +81,8 @@ fn float(input: Span) -> IResult { opt(preceded(char('.'), decimal)), one_of("eE"), opt(alt(( - tag_token(TokenType::PLUS), - tag_token(TokenType::MINUS), + tag_token_symbol(TokenType::PLUS), + tag_token_symbol(TokenType::MINUS), ))), decimal, ))), // Case three: 42. and 42.42 diff --git a/src/nomparser/control.rs b/src/nomparser/control.rs index 506f84a34..5df0eeb45 100644 --- a/src/nomparser/control.rs +++ b/src/nomparser/control.rs @@ -51,12 +51,12 @@ use super::*; pub fn if_statement(input: Span) -> IResult> { map_res( delspace(tuple(( - tag_token(TokenType::IF), + tag_token_word(TokenType::IF), parse_with_ex(logic_exp, true), statement_block, opt(delspace(comment)), opt(preceded( - tag_token(TokenType::ELSE), + tag_token_word(TokenType::ELSE), alt(( if_statement, map_res(statement_block, |n| res_enum(n.into())), @@ -104,7 +104,7 @@ pub fn if_statement(input: Span) -> IResult> { pub fn while_statement(input: Span) -> IResult> { map_res( delspace(tuple(( - tag_token(TokenType::WHILE), + tag_token_word(TokenType::WHILE), alt_except( logic_exp, "{", @@ -166,11 +166,11 @@ pub fn while_statement(input: Span) -> IResult> { pub fn for_statement(input: Span) -> IResult> { map_res( delspace(tuple(( - tag_token(TokenType::FOR), + tag_token_word(TokenType::FOR), opt(alt((assignment, new_variable))), - tag_token(TokenType::SEMI), + tag_token_symbol(TokenType::SEMI), logic_exp, - tag_token(TokenType::SEMI), + tag_token_symbol(TokenType::SEMI), opt(assignment), statement_block, opt(delspace(comment)), @@ -204,8 +204,8 @@ pub fn for_statement(input: Span) -> IResult> { pub fn break_statement(input: Span) -> IResult> { map_res( tuple(( - tag_token(TokenType::BREAK), - tag_token(TokenType::SEMI), + tag_token_word(TokenType::BREAK), + tag_token_symbol(TokenType::SEMI), opt(delspace(comment)), )), |(_, _, optcomment)| { @@ -228,8 +228,8 @@ pub fn break_statement(input: Span) -> IResult> { pub fn continue_statement(input: Span) -> IResult> { map_res( tuple(( - tag_token(TokenType::CONTINUE), - tag_token(TokenType::SEMI), + tag_token_word(TokenType::CONTINUE), + tag_token_symbol(TokenType::SEMI), opt(delspace(comment)), )), |(_, _, optcomment)| { diff --git a/src/nomparser/expression.rs b/src/nomparser/expression.rs index 157065373..aca32a125 100644 --- a/src/nomparser/expression.rs +++ b/src/nomparser/expression.rs @@ -56,7 +56,10 @@ fn unary_exp(input: Span) -> IResult> { pointer_exp, map_res( tuple(( - alt((tag_token(TokenType::MINUS), tag_token(TokenType::NOT))), + alt(( + tag_token_symbol(TokenType::MINUS), + tag_token_symbol(TokenType::NOT), + )), pointer_exp, )), |((op, op_range), exp)| { @@ -83,8 +86,8 @@ pub fn pointer_exp(input: Span) -> IResult> { map_res( delspace(pair( many0(alt(( - tag_token(TokenType::TAKE_PTR), - tag_token(TokenType::TAKE_VAL), + tag_token_symbol(TokenType::TAKE_PTR), + tag_token_symbol(TokenType::TAKE_VAL), ))), complex_exp, )), @@ -221,7 +224,7 @@ fn primary_exp(input: Span) -> IResult> { fn take_exp_op(input: Span) -> IResult>)> { delspace(map_res( preceded( - tag_token(TokenType::DOT), + tag_token_symbol(TokenType::DOT), pair(opt(identifier), many0(comment)), ), |(idx, coms)| Ok::<_, Error>((ComplexOp::FieldOp(idx), coms)), @@ -236,9 +239,9 @@ fn take_exp_op(input: Span) -> IResult>)> { fn parantheses_exp(input: Span) -> IResult> { map_res( delimited( - tag_token(TokenType::LPAREN), + tag_token_symbol(TokenType::LPAREN), parse_with_ex(logic_exp, false), - tag_token(TokenType::RPAREN), + tag_token_symbol(TokenType::RPAREN), ), |exp| { res_enum( diff --git a/src/nomparser/function.rs b/src/nomparser/function.rs index 29b329641..cce823a75 100644 --- a/src/nomparser/function.rs +++ b/src/nomparser/function.rs @@ -48,21 +48,21 @@ pub fn function_def(input: Span) -> IResult> { map_res( tuple(( many0(del_newline_or_space!(comment)), - tag_token(TokenType::FN), + tag_token_word(TokenType::FN), identifier, opt(generic_type_def), - tag_token(TokenType::LPAREN), + tag_token_symbol(TokenType::LPAREN), del_newline_or_space!(separated_list0( - tag_token(TokenType::COMMA), + tag_token_symbol(TokenType::COMMA), del_newline_or_space!(typed_identifier), )), - tag_token(TokenType::RPAREN), + tag_token_symbol(TokenType::RPAREN), type_name, alt(( map_res(statement_block, |b| { Ok::<_, Error>((Some(b.clone()), b.range)) }), - map_res(tag_token(TokenType::SEMI), |(_, range)| { + map_res(tag_token_symbol(TokenType::SEMI), |(_, range)| { Ok::<_, Error>((None, range)) }), )), @@ -104,12 +104,12 @@ pub fn call_function_op(input: Span) -> IResult impl Fn(Span) -> IResult { +pub fn tag_token_symbol(token: TokenType) -> impl Fn(Span) -> IResult { move |input| { map_res(delspace(tag(token.get_str())), |_out: Span| { let end = _out.take_split(token.get_str().len()).0; @@ -17,6 +19,21 @@ pub fn tag_token(token: TokenType) -> impl Fn(Span) -> IResult impl Fn(Span) -> IResult { + move |input| { + let (s1, s2): (LocatedSpan<&str, bool>, LocatedSpan<&str, bool>) = + preceded(space0, tag(token.get_str()))(input)?; + if s1.starts_with(|c: char| is_alphanumeric(c as u8) || c == '_') { + return Err(nom::Err::Error(nom::error::Error::new( + s2, + nom::error::ErrorKind::Tag, + ))); + } else { + let end = s2.take_split(token.get_str().len()).0; + return Ok((s1, (token, Range::new(s2, end)))); + } + } +} pub fn delspace(parser: G) -> impl FnMut(I) -> IResult where G: Parser, diff --git a/src/nomparser/identifier.rs b/src/nomparser/identifier.rs index 023fb7ca6..993fab3f8 100644 --- a/src/nomparser/identifier.rs +++ b/src/nomparser/identifier.rs @@ -37,9 +37,12 @@ use super::*; pub fn extern_identifier(input: Span) -> IResult> { delspace(map_res( tuple(( - separated_list1(tag_token(TokenType::DOUBLE_COLON), delspace(identifier)), - opt(tag_token(TokenType::DOUBLE_COLON)), // 容忍未写完的语句 - opt(tag_token(TokenType::COLON)), // 容忍未写完的语句 + separated_list1( + tag_token_symbol(TokenType::DOUBLE_COLON), + delspace(identifier), + ), + opt(tag_token_symbol(TokenType::DOUBLE_COLON)), // 容忍未写完的语句 + opt(tag_token_symbol(TokenType::COLON)), // 容忍未写完的语句 )), |(mut ns, opt, opt2)| { let id = ns.pop().unwrap(); @@ -88,7 +91,7 @@ pub fn typed_identifier(input: Span) -> IResult> delspace(map_res( tuple(( identifier, - tag_token(TokenType::COLON), + tag_token_symbol(TokenType::COLON), opt(type_name), opt(comment), )), diff --git a/src/nomparser/implement.rs b/src/nomparser/implement.rs index 377fabefd..70c6a81cb 100644 --- a/src/nomparser/implement.rs +++ b/src/nomparser/implement.rs @@ -50,13 +50,13 @@ use super::*; pub fn impl_def(input: Span) -> IResult> { map_res( tuple(( - tag_token(TokenType::IMPL), - opt(pair(type_name, tag_token(TokenType::FOR))), + tag_token_word(TokenType::IMPL), + opt(pair(type_name, tag_token_word(TokenType::FOR))), type_name, - del_newline_or_space!(tag_token(TokenType::LBRACE)), + del_newline_or_space!(tag_token_symbol(TokenType::LBRACE)), many0(del_newline_or_space!(function_def)), many0(comment), - del_newline_or_space!(tag_token(TokenType::RBRACE)), + del_newline_or_space!(tag_token_symbol(TokenType::RBRACE)), )), |(_, o, tp, (_, start), func_def, comment0, (_, end))| { res_box(Box::new(TopLevel::ImplDef(ImplNode { diff --git a/src/nomparser/macros.rs b/src/nomparser/macros.rs index d4216d776..361ed0168 100644 --- a/src/nomparser/macros.rs +++ b/src/nomparser/macros.rs @@ -16,7 +16,7 @@ macro_rules! parse_bin_ops { many0(tuple(( alt(( $( - tag_token(TokenType::$op), + tag_token_symbol(TokenType::$op), )* )), $exp, @@ -35,7 +35,7 @@ macro_rules! parse_bin_ops { /// 所有分号结尾的statement都应该使用这个宏来处理分号 macro_rules! semi_statement { ($e:expr) => { - alt((terminated($e, tag_token(TokenType::SEMI)), map_res(tuple(($e,recognize(many0(alt((tag("\n"), tag("\r\n"), preceded(many0(tag(" ")),tag("\n")), tag("\t"))))))), |(node,e)|{ + alt((terminated($e, tag_token_symbol(TokenType::SEMI)), map_res(tuple(($e,recognize(many0(alt((tag("\n"), tag("\r\n"), preceded(many0(tag(" ")),tag("\n")), tag("\t"))))))), |(node,e)|{ let range = node.range(); let r = Range::new(e,e); res_enum(StErrorNode{ diff --git a/src/nomparser/pkg.rs b/src/nomparser/pkg.rs index aad7f2499..7fe3f264a 100644 --- a/src/nomparser/pkg.rs +++ b/src/nomparser/pkg.rs @@ -21,11 +21,11 @@ use super::*; pub fn use_statement(input: Span) -> IResult> { map_res( preceded( - tag_token(TokenType::USE), + tag_token_word(TokenType::USE), delspace(tuple(( - separated_list1(tag_token(TokenType::DOUBLE_COLON), identifier), - opt(tag_token(TokenType::DOUBLE_COLON)), - opt(tag_token(TokenType::COLON)), + separated_list1(tag_token_symbol(TokenType::DOUBLE_COLON), identifier), + opt(tag_token_symbol(TokenType::DOUBLE_COLON)), + opt(tag_token_symbol(TokenType::COLON)), ))), ), |(ns, opt, opt2)| { diff --git a/src/nomparser/statement.rs b/src/nomparser/statement.rs index e3d8f9987..0bf17250e 100644 --- a/src/nomparser/statement.rs +++ b/src/nomparser/statement.rs @@ -27,7 +27,7 @@ use super::*; fn empty_statement(input: Span) -> IResult> { map_res( - preceded(tag_token(TokenType::SEMI), opt(delspace(comment))), + preceded(tag_token_symbol(TokenType::SEMI), opt(delspace(comment))), |optcomment| { let comments = if let Some(com) = optcomment { vec![vec![com]] @@ -55,9 +55,9 @@ fn empty_statement(input: Span) -> IResult> { pub fn statement_block(input: Span) -> IResult { delspace(map_res( tuple(( - del_newline_or_space!(tag_token(TokenType::LBRACE)), + del_newline_or_space!(tag_token_symbol(TokenType::LBRACE)), many0(del_newline_or_space!(statement)), - del_newline_or_space!(tag_token(TokenType::RBRACE)), + del_newline_or_space!(tag_token_symbol(TokenType::RBRACE)), )), |((_, start), v, (_, end))| { let range = start.start.to(end.end); @@ -107,10 +107,10 @@ fn statement(input: Span) -> IResult> { pub fn new_variable(input: Span) -> IResult> { delspace(map_res( tuple(( - tag_token(TokenType::LET), + tag_token_word(TokenType::LET), identifier, - opt(pair(tag_token(TokenType::COLON), type_name)), - opt(pair(tag_token(TokenType::ASSIGN), logic_exp)), + opt(pair(tag_token_symbol(TokenType::COLON), type_name)), + opt(pair(tag_token_symbol(TokenType::ASSIGN), logic_exp)), )), |((_, start), a, tp, v)| { let mut end = a.range.end; @@ -140,7 +140,7 @@ pub fn new_variable(input: Span) -> IResult> { #[test_parser("a = 1")] pub fn assignment(input: Span) -> IResult> { delspace(map_res( - tuple((pointer_exp, tag_token(TokenType::ASSIGN), logic_exp)), + tuple((pointer_exp, tag_token_symbol(TokenType::ASSIGN), logic_exp)), |(left, _op, right)| { let range = left.range().start.to(right.range().end); res_enum( @@ -168,9 +168,9 @@ pub fn assignment(input: Span) -> IResult> { fn return_statement(input: Span) -> IResult> { delspace(map_res( tuple(( - tag_token(TokenType::RETURN), + tag_token_word(TokenType::RETURN), opt(logic_exp), - tag_token(TokenType::SEMI), + tag_token_symbol(TokenType::SEMI), opt(delspace(comment)), )), |((_, range), val, _, optcomment)| { @@ -207,9 +207,9 @@ fn return_statement(input: Span) -> IResult> { pub fn global_variable(input: Span) -> IResult> { delspace(map_res( tuple(( - tag_token(TokenType::CONST), + tag_token_word(TokenType::CONST), identifier, - tag_token(TokenType::ASSIGN), + tag_token_symbol(TokenType::ASSIGN), logic_exp, )), |(_, var, _, exp)| { diff --git a/src/nomparser/string_literal.rs b/src/nomparser/string_literal.rs index c87ee2bce..5c0c8573b 100644 --- a/src/nomparser/string_literal.rs +++ b/src/nomparser/string_literal.rs @@ -165,9 +165,9 @@ where pub fn string_literal(input: Span) -> IResult> { map_res( tuple(( - tag_token(TokenType::DOUBLE_QUOTE), + tag_token_symbol(TokenType::DOUBLE_QUOTE), parse_string_content, - tag_token(TokenType::DOUBLE_QUOTE), + tag_token_symbol(TokenType::DOUBLE_QUOTE), )), |((_, st), s, (_, end))| { res_enum( diff --git a/src/nomparser/structure.rs b/src/nomparser/structure.rs index 94b2de852..aa50eddc7 100644 --- a/src/nomparser/structure.rs +++ b/src/nomparser/structure.rs @@ -29,16 +29,16 @@ pub fn struct_def(input: Span) -> IResult> { map_res( tuple(( many0(del_newline_or_space!(comment)), - tag_token(TokenType::STRUCT), + tag_token_word(TokenType::STRUCT), identifier, opt(generic_type_def), - del_newline_or_space!(tag_token(TokenType::LBRACE)), + del_newline_or_space!(tag_token_symbol(TokenType::LBRACE)), many0(tuple(( del_newline_or_space!(typed_identifier), - opt(tag_token(TokenType::SEMI)), + opt(tag_token_symbol(TokenType::SEMI)), opt(comment), ))), - del_newline_or_space!(tag_token(TokenType::RBRACE)), + del_newline_or_space!(tag_token_symbol(TokenType::RBRACE)), )), |(doc, (_, start), id, generics, _, fields, (_, end))| { let range = start.start.to(end.end); @@ -81,7 +81,7 @@ pub fn struct_def(input: Span) -> IResult> { /// special: del newline or space fn struct_init_field(input: Span) -> IResult> { del_newline_or_space!(map_res( - tuple((identifier, tag_token(TokenType::COLON), logic_exp,)), + tuple((identifier, tag_token_symbol(TokenType::COLON), logic_exp,)), |(id, _, exp)| { let range = id.range.start.to(exp.range().end); Ok::<_, Error>(Box::new(StructInitFieldNode { @@ -111,14 +111,14 @@ pub fn struct_init(input: Span) -> IResult> { tuple(( type_name, opt(generic_param_def), - del_newline_or_space!(tag_token(TokenType::LBRACE)), + del_newline_or_space!(tag_token_symbol(TokenType::LBRACE)), alt(( map_res( pair( many0(tuple(( terminated( del_newline_or_space!(struct_init_field), - tag_token(TokenType::COMMA), + tag_token_symbol(TokenType::COMMA), ), many0(comment), ))), @@ -144,7 +144,7 @@ pub fn struct_init(input: Span) -> IResult> { }), )), many0(comment), - del_newline_or_space!(tag_token(TokenType::RBRACE)), + del_newline_or_space!(tag_token_symbol(TokenType::RBRACE)), )), |(name, generic_params, _, (fields, lcomment), rcomment, _)| { let range = if fields.len() > 0 { diff --git a/src/nomparser/types.rs b/src/nomparser/types.rs index 21f22ae31..caf15b8f8 100644 --- a/src/nomparser/types.rs +++ b/src/nomparser/types.rs @@ -26,7 +26,7 @@ use super::*; pub fn type_name(input: Span) -> IResult> { delspace(map_res( pair( - many0(tag_token(TokenType::TAKE_VAL)), + many0(tag_token_symbol(TokenType::TAKE_VAL)), alt((basic_type, array_type)), ), |(pts, n)| { @@ -66,11 +66,11 @@ fn basic_type(input: Span) -> IResult> { fn array_type(input: Span) -> IResult> { map_res( tuple(( - tag_token(TokenType::LBRACKET), + tag_token_symbol(TokenType::LBRACKET), type_name, - tag_token(TokenType::MUL), + tag_token_symbol(TokenType::MUL), number, - tag_token(TokenType::RBRACKET), + tag_token_symbol(TokenType::RBRACKET), )), |(_, tp, _, size, _)| { let range = size.range().start.to(tp.range().end); @@ -94,9 +94,9 @@ fn array_type(input: Span) -> IResult> { pub fn generic_type_def(input: Span) -> IResult> { map_res( tuple(( - tag_token(TokenType::LESS), - separated_list1(tag_token(TokenType::GENERIC_SEP), identifier), - tag_token(TokenType::GREATER), + tag_token_symbol(TokenType::LESS), + separated_list1(tag_token_symbol(TokenType::GENERIC_SEP), identifier), + tag_token_symbol(TokenType::GREATER), )), |(lf, ids, ri)| { let range = lf.1.start.to(ri.1.end); @@ -117,15 +117,15 @@ pub fn generic_type_def(input: Span) -> IResult> { pub fn generic_param_def(input: Span) -> IResult> { map_res( tuple(( - tag_token(TokenType::LESS), + tag_token_symbol(TokenType::LESS), separated_list1( - tag_token(TokenType::GENERIC_SEP), + tag_token_symbol(TokenType::GENERIC_SEP), alt(( map_res(type_name, |x| Ok::<_, Error>(Some(x))), - map_res(tag_token(TokenType::INGNORE), |_| Ok::<_, Error>(None)), + map_res(tag_token_word(TokenType::INGNORE), |_| Ok::<_, Error>(None)), )), ), - tag_token(TokenType::GREATER), + tag_token_symbol(TokenType::GREATER), )), |(lf, ids, ri)| { let range = lf.1.start.to(ri.1.end); @@ -148,12 +148,12 @@ pub fn generic_param_def(input: Span) -> IResult> { pub fn trait_def(input: Span) -> IResult> { map_res( tuple(( - tag_token(TokenType::TRAIT), + tag_token_word(TokenType::TRAIT), identifier, opt(generic_type_def), - del_newline_or_space!(tag_token(TokenType::LBRACE)), + del_newline_or_space!(tag_token_symbol(TokenType::LBRACE)), many0(del_newline_or_space!(function_def)), - del_newline_or_space!(tag_token(TokenType::RBRACE)), + del_newline_or_space!(tag_token_symbol(TokenType::RBRACE)), )), |(_, id, generics, _, defs, (_, rr))| { let range = id.range().start.to(rr.end); From 0f08ac3148fbd7b3c421ac46e84e58ecf930e5b2 Mon Sep 17 00:00:00 2001 From: cjw Date: Tue, 27 Dec 2022 17:51:03 +0800 Subject: [PATCH 2/4] test: add parser tests --- src/nomparser/array.rs | 10 ++++++++++ src/nomparser/comment.rs | 4 ++++ src/nomparser/constval.rs | 4 ++++ src/nomparser/control.rs | 24 +++++++++++++++++++++++- src/nomparser/function.rs | 3 ++- src/nomparser/implement.rs | 10 +++++++++- src/nomparser/pkg.rs | 4 +++- src/nomparser/statement.rs | 6 +++++- src/nomparser/structure.rs | 8 +++++++- src/nomparser/types.rs | 7 ++++++- 10 files changed, 73 insertions(+), 7 deletions(-) diff --git a/src/nomparser/array.rs b/src/nomparser/array.rs index 1c3472924..ce1ff1578 100644 --- a/src/nomparser/array.rs +++ b/src/nomparser/array.rs @@ -1,5 +1,6 @@ use std::fmt::Error; +use internal_macro::test_parser; use nom::{ branch::alt, bytes::complete::tag, @@ -18,6 +19,14 @@ use crate::{ use super::*; +#[test_parser("[1,2,3]")] +#[test_parser( + "[ + 1, + 2, + x + ]" +)] pub fn array_init(input: Span) -> IResult> { map_res( tuple(( @@ -35,6 +44,7 @@ pub fn array_init(input: Span) -> IResult> { )(input) } +#[test_parser("[123]")] /// ```ebnf /// array_element_op = ('[' logic_exp ']') ; /// ``` diff --git a/src/nomparser/comment.rs b/src/nomparser/comment.rs index f8c8aee49..6fb801a42 100644 --- a/src/nomparser/comment.rs +++ b/src/nomparser/comment.rs @@ -1,5 +1,6 @@ use crate::nomparser::Span; use crate::{ast::node::comment::CommentNode, ast::range::Range}; +use internal_macro::{test_parser, test_parser_error}; use nom::{ branch::alt, bytes::complete::{tag, take_until}, @@ -11,6 +12,9 @@ use nom_locate::LocatedSpan; use super::*; +#[test_parser("//123")] +#[test_parser("/// 123\n")] +#[test_parser_error("/ / 123\n")] pub fn comment(input: Span) -> IResult> { map_res( pair( diff --git a/src/nomparser/constval.rs b/src/nomparser/constval.rs index 511b37cfb..d0201e9c7 100644 --- a/src/nomparser/constval.rs +++ b/src/nomparser/constval.rs @@ -57,6 +57,10 @@ pub fn bool_const(input: Span) -> IResult> { ))(input) } +#[test_parser("123")] +#[test_parser("12_3")] +#[test_parser("1_2_3")] +#[test_parser_error("1 23")] fn decimal(input: Span) -> IResult { recognize(many1(terminated(one_of("0123456789"), many0(char('_')))))(input) } diff --git a/src/nomparser/control.rs b/src/nomparser/control.rs index 5df0eeb45..fc8052923 100644 --- a/src/nomparser/control.rs +++ b/src/nomparser/control.rs @@ -45,6 +45,13 @@ use super::*; return; }"# )] +#[test_parser_error( + "ifa > 1 { + a = 1; +} else { + a = 2; +}" +)] /// ```ebnf /// if_statement = "if" logic_exp statement_block ("else" (if_statement | statement_block))? ; /// ``` @@ -98,6 +105,12 @@ pub fn if_statement(input: Span) -> IResult> { } " )] +#[test_parser_error( + "whiletrue { + let a = b; +} +" +)] /// ```ebnf /// while_statement = "while" logic_exp statement_block ; /// ``` @@ -159,7 +172,16 @@ pub fn while_statement(input: Span) -> IResult> { }" )] - +#[test_parser_error( + "forlet i = 0; i < 5; i = i + 1{ + + }" +)] +#[test_parser_error( + "for leti = 0; i < 5; i = i + 1{ + + }" +)] /// ```enbf /// for_statement = "for" (assignment | new_variable) ";" logic_exp ";" assignment statement_block; /// ``` diff --git a/src/nomparser/function.rs b/src/nomparser/function.rs index cce823a75..d5f3952fa 100644 --- a/src/nomparser/function.rs +++ b/src/nomparser/function.rs @@ -12,7 +12,7 @@ use nom::{ use crate::nomparser::Span; use crate::{ast::node::function::FuncDefNode, ast::tokens::TokenType}; -use internal_macro::test_parser; +use internal_macro::{test_parser, test_parser_error}; use super::*; @@ -44,6 +44,7 @@ use super::*; " )] #[test_parser("fn f( \n) int;")] +#[test_parser_error("fnf( \n) int;")] pub fn function_def(input: Span) -> IResult> { map_res( tuple(( diff --git a/src/nomparser/implement.rs b/src/nomparser/implement.rs index 70c6a81cb..d03fbc0de 100644 --- a/src/nomparser/implement.rs +++ b/src/nomparser/implement.rs @@ -8,7 +8,7 @@ use nom::{ IResult, }; -use internal_macro::test_parser; +use internal_macro::{test_parser, test_parser_error}; use super::*; @@ -47,6 +47,14 @@ use super::*; } }" )] +#[test_parser_error( + "impla::b::c { + fn f(x: int) int { + x = x+1; + return 0; + } + }" +)] pub fn impl_def(input: Span) -> IResult> { map_res( tuple(( diff --git a/src/nomparser/pkg.rs b/src/nomparser/pkg.rs index 7fe3f264a..cbc9ecbb3 100644 --- a/src/nomparser/pkg.rs +++ b/src/nomparser/pkg.rs @@ -7,7 +7,7 @@ use nom::{ use crate::nomparser::Span; use crate::{ast::node::pkg::UseNode, ast::tokens::TokenType}; -use internal_macro::test_parser; +use internal_macro::{test_parser, test_parser_error}; use super::*; @@ -18,6 +18,8 @@ use super::*; #[test_parser("use a::")] #[test_parser("use a")] #[test_parser("use a:")] +#[test_parser_error("usea")] +#[test_parser_error("usea:")] pub fn use_statement(input: Span) -> IResult> { map_res( preceded( diff --git a/src/nomparser/statement.rs b/src/nomparser/statement.rs index 0bf17250e..e674103dd 100644 --- a/src/nomparser/statement.rs +++ b/src/nomparser/statement.rs @@ -24,7 +24,7 @@ use internal_macro::{test_parser, test_parser_error}; use std::fmt::Error; use super::*; - +#[test_parser(";")] fn empty_statement(input: Span) -> IResult> { map_res( preceded(tag_token_symbol(TokenType::SEMI), opt(delspace(comment))), @@ -104,6 +104,7 @@ fn statement(input: Span) -> IResult> { } #[test_parser("let a = 1")] +#[test_parser_error("leta = 1")] pub fn new_variable(input: Span) -> IResult> { delspace(map_res( tuple(( @@ -161,6 +162,8 @@ pub fn assignment(input: Span) -> IResult> { #[test_parser("return;")] #[test_parser("return a;")] #[test_parser("return 1 + 2;")] +#[test_parser_error("returntrue;")] +#[test_parser_error("return1 + 2;")] #[test_parser_error("return a = 2;")] // ``` // return_statement = "return" logic_exp newline ; @@ -204,6 +207,7 @@ fn return_statement(input: Span) -> IResult> { } #[test_parser("const a = 1")] +#[test_parser_error("consta = 1")] pub fn global_variable(input: Span) -> IResult> { delspace(map_res( tuple(( diff --git a/src/nomparser/structure.rs b/src/nomparser/structure.rs index aa50eddc7..6919e20fc 100644 --- a/src/nomparser/structure.rs +++ b/src/nomparser/structure.rs @@ -6,7 +6,7 @@ use crate::{ ast::node::{types::StructInitNode, NodeEnum, RangeTrait}, ast::{node::types::StructInitFieldNode, tokens::TokenType}, }; -use internal_macro::test_parser; +use internal_macro::{test_parser, test_parser_error}; use nom::{ branch::alt, bytes::complete::tag, @@ -25,6 +25,12 @@ use super::*; myname2: int; }" )] +#[test_parser_error( + "structmystruct { + myname: int;//123 + myname2: int; +}" +)] pub fn struct_def(input: Span) -> IResult> { map_res( tuple(( diff --git a/src/nomparser/types.rs b/src/nomparser/types.rs index caf15b8f8..01d3f86ba 100644 --- a/src/nomparser/types.rs +++ b/src/nomparser/types.rs @@ -11,7 +11,7 @@ use crate::{ tokens::TokenType, }, }; -use internal_macro::test_parser; +use internal_macro::{test_parser, test_parser_error}; use nom::{ branch::alt, bytes::complete::tag, @@ -145,6 +145,11 @@ pub fn generic_param_def(input: Span) -> IResult> { fn a() A; }" )] +#[test_parser_error( + "traitmytrait { + fn a() A; +}" +)] pub fn trait_def(input: Span) -> IResult> { map_res( tuple(( From c2c1c0fd72a6a33af4ccfd2c3c21a9c75b186c02 Mon Sep 17 00:00:00 2001 From: cjw Date: Tue, 27 Dec 2022 18:04:04 +0800 Subject: [PATCH 3/4] test: rm incorrect test --- src/nomparser/control.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/nomparser/control.rs b/src/nomparser/control.rs index fc8052923..0d4a5e452 100644 --- a/src/nomparser/control.rs +++ b/src/nomparser/control.rs @@ -177,11 +177,6 @@ pub fn while_statement(input: Span) -> IResult> { }" )] -#[test_parser_error( - "for leti = 0; i < 5; i = i + 1{ - - }" -)] /// ```enbf /// for_statement = "for" (assignment | new_variable) ";" logic_exp ";" assignment statement_block; /// ``` From dc10277a53544106b9240e113ad473abad75b6be Mon Sep 17 00:00:00 2001 From: cjw Date: Tue, 27 Dec 2022 18:44:41 +0800 Subject: [PATCH 4/4] docs: tag_token_word --- src/nomparser/helper.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/nomparser/helper.rs b/src/nomparser/helper.rs index b54812382..aaa65bf54 100644 --- a/src/nomparser/helper.rs +++ b/src/nomparser/helper.rs @@ -19,6 +19,8 @@ pub fn tag_token_symbol(token: TokenType) -> impl Fn(Span) -> IResult impl Fn(Span) -> IResult { move |input| { let (s1, s2): (LocatedSpan<&str, bool>, LocatedSpan<&str, bool>) =