Skip to content

Commit c9adff3

Browse files
committed
Moved conditionally_opt_whitespace to whitespace module.
Added `expr_keyword_opt_expr` parser.
1 parent 8a5b34a commit c9adff3

5 files changed

Lines changed: 61 additions & 45 deletions

File tree

rusty_parser/src/core/dim_name.rs

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ use rusty_pc::*;
44
use crate::core::var_name;
55
use crate::input::StringView;
66
use crate::pc_specific::*;
7-
use crate::{ParserError, *};
7+
use crate::{
8+
ArrayDimensions, BareName, BuiltInStyle, DimList, DimType, Name, ParserError, ToBareName, TypeQualifier, TypedName
9+
};
810

911
pub type DimVar = TypedName<DimType>;
1012
pub type DimVarPos = Positioned<DimVar>;
@@ -122,10 +124,10 @@ where
122124
mod array_dimensions {
123125
use rusty_pc::*;
124126

125-
use crate::expr::{expression_pos_p, opt_second_expression_after_keyword};
127+
use crate::expr::expr_keyword_opt_expr;
126128
use crate::input::StringView;
127129
use crate::pc_specific::*;
128-
use crate::{ParserError, *};
130+
use crate::{ArrayDimension, ArrayDimensions, Keyword, ParserError};
129131

130132
pub fn array_dimensions_p()
131133
-> impl Parser<StringView, Output = ArrayDimensions, Error = ParserError> {
@@ -137,12 +139,7 @@ mod array_dimensions {
137139
// paren_expr ws* TO ws* paren_expr
138140
fn array_dimension_p() -> impl Parser<StringView, Output = ArrayDimension, Error = ParserError>
139141
{
140-
opt_second_expression_after_keyword(
141-
expression_pos_p(),
142-
Keyword::To,
143-
ExpressionTrait::is_parenthesis,
144-
)
145-
.map(|(l, opt_r)| match opt_r {
142+
expr_keyword_opt_expr(Keyword::To).map(|(l, opt_r)| match opt_r {
146143
Some(r) => ArrayDimension {
147144
lbound: Some(l),
148145
ubound: r,
@@ -158,12 +155,12 @@ mod array_dimensions {
158155
mod type_definition {
159156
use rusty_pc::*;
160157

161-
use crate::core::VarNameCtx;
158+
use crate::core::{VarNameCtx, user_defined_type};
162159
use crate::expr::expression_pos_p;
163160
use crate::input::StringView;
164161
use crate::pc_specific::*;
165162
use crate::tokens::star_ws;
166-
use crate::{ParserError, *};
163+
use crate::{BuiltInStyle, DimType, ExpressionPos, Keyword, ParserError, TypeQualifier};
167164

168165
pub fn extended_type()
169166
-> impl Parser<StringView, VarNameCtx, Output = DimType, Error = ParserError> {

rusty_parser/src/core/select_case.rs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -105,11 +105,11 @@ mod case_expression_parser {
105105
use rusty_common::Positioned;
106106
use rusty_pc::*;
107107

108-
use crate::expr::{expression_pos_p, opt_second_expression_after_keyword};
108+
use crate::expr::{expr_keyword_opt_expr, expression_pos_p};
109109
use crate::input::StringView;
110110
use crate::pc_specific::*;
111111
use crate::tokens::{TokenType, any_token};
112-
use crate::{CaseExpression, ExpressionTrait, Keyword, Operator, ParserError};
112+
use crate::{CaseExpression, Keyword, Operator, ParserError};
113113

114114
pub fn parser() -> impl Parser<StringView, Output = CaseExpression, Error = ParserError> {
115115
case_is().or(simple_or_range())
@@ -140,12 +140,7 @@ mod case_expression_parser {
140140
}
141141

142142
fn simple_or_range() -> impl Parser<StringView, Output = CaseExpression, Error = ParserError> {
143-
opt_second_expression_after_keyword(
144-
expression_pos_p(),
145-
Keyword::To,
146-
ExpressionTrait::is_parenthesis,
147-
)
148-
.map(|(left, opt_right)| match opt_right {
143+
expr_keyword_opt_expr(Keyword::To).map(|(left, opt_right)| match opt_right {
149144
Some(right) => CaseExpression::Range(left, right),
150145
_ => CaseExpression::Simple(left),
151146
})

rusty_parser/src/expr/opt_second_expression.rs

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
use rusty_pc::and::TupleCombiner;
2-
use rusty_pc::{IifParser, Parser, ParserErrorTrait};
2+
use rusty_pc::{Parser, ParserErrorTrait};
33

44
use crate::error::ParserError;
55
use crate::expr::parsers::ws_expr_pos_p;
66
use crate::input::StringView;
7-
use crate::pc_specific::{keyword, whitespace_ignoring};
7+
use crate::pc_specific::{conditionally_opt_whitespace, keyword};
88
use crate::{ExpressionPos, Keyword};
99

1010
/// Parses an optional second expression that follows the first expression
@@ -55,24 +55,3 @@ fn ws_keyword(k: Keyword) -> impl Parser<StringView, bool, Error = ParserError>
5555
fn err(keyword: Keyword) -> ParserError {
5656
ParserError::expected(&format!("expression after {}", keyword)).to_fatal()
5757
}
58-
59-
/// Creates a parser that parses whitespace,
60-
/// conditionally allowing it to be missing.
61-
/// When [allow_none] is false, whitespace is mandatory.
62-
/// When [allow_none] is true, the whitespace can be missing.
63-
/// This is typically the case when the previously parsed
64-
/// token was a right side parenthesis.
65-
///
66-
/// Examples
67-
///
68-
/// * `(1 + 2)AND` no whitespace is required before `AND`
69-
/// * `1 + 2AND` the lack of whitespace before `AND` is an error
70-
pub(super) fn conditionally_opt_whitespace()
71-
-> impl Parser<StringView, bool, Output = (), Error = ParserError> {
72-
IifParser::new(
73-
// allow none
74-
whitespace_ignoring().to_option().map_to_unit(),
75-
// whitespace is required
76-
whitespace_ignoring(),
77-
)
78-
}

rusty_parser/src/expr/parsers.rs

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
use rusty_pc::and::{KeepLeftCombiner, VecCombiner};
1+
use rusty_pc::and::{KeepLeftCombiner, TupleCombiner, VecCombiner};
22
use rusty_pc::*;
33

4-
use crate::expr::opt_second_expression::conditionally_opt_whitespace;
54
use crate::input::StringView;
65
use crate::pc_specific::*;
76
use crate::tokens::comma_ws;
@@ -136,3 +135,28 @@ pub fn expr_ws_followed_by(
136135
KeepLeftCombiner,
137136
)
138137
}
138+
139+
/// Parses an expression, followed optionally by a keyword and a second expression.
140+
/// If the keyword is present, the second expression is mandatory.
141+
///
142+
/// Examples: `FOR I = 1 TO 100 [STEP 5]`, `CASE 1 [TO 2]`
143+
pub fn expr_keyword_opt_expr(
144+
keyword: Keyword,
145+
) -> impl Parser<StringView, Output = (ExpressionPos, Option<ExpressionPos>), Error = ParserError> {
146+
expression_pos_p().then_with_in_context(
147+
opt_keyword_expr(keyword),
148+
ExpressionTrait::is_parenthesis,
149+
TupleCombiner,
150+
)
151+
}
152+
153+
/// Parses the optional `TO expr` part (e.g. `CASE 1 TO 2`)
154+
fn opt_keyword_expr(
155+
keyword: Keyword,
156+
) -> impl Parser<StringView, bool, Output = Option<ExpressionPos>, Error = ParserError> {
157+
let msg = format!("expression after {}", keyword);
158+
conditionally_opt_whitespace()
159+
.and_keep_right(keyword_ignoring(keyword).no_context())
160+
.and_keep_right(ws_expr_pos_p().or_expected(&msg).no_context())
161+
.to_option()
162+
}

rusty_parser/src/pc_specific/whitespace.rs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use rusty_pc::{Parser, SurroundMode, surround};
1+
use rusty_pc::{IifParser, Parser, SurroundMode, surround};
22

33
use crate::ParserError;
44
use crate::input::StringView;
@@ -70,3 +70,24 @@ where
7070
{
7171
demand_ws().no_context().and_keep_right(parser)
7272
}
73+
74+
/// Creates a parser that parses whitespace,
75+
/// conditionally allowing it to be missing.
76+
/// When [allow_none] is false, whitespace is mandatory.
77+
/// When [allow_none] is true, the whitespace can be missing.
78+
/// This is typically the case when the previously parsed
79+
/// token was a right side parenthesis.
80+
///
81+
/// Examples
82+
///
83+
/// * `(1 + 2)AND` no whitespace is required before `AND`
84+
/// * `1 + 2AND` the lack of whitespace before `AND` is an error
85+
pub fn conditionally_opt_whitespace()
86+
-> impl Parser<StringView, bool, Output = (), Error = ParserError> {
87+
IifParser::new(
88+
// allow none
89+
opt_ws(),
90+
// whitespace is required
91+
whitespace_ignoring(),
92+
)
93+
}

0 commit comments

Comments
 (0)