diff --git a/NEWS.md b/NEWS.md index bb53a9b..4ddb742 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,7 @@ # tidyxl 1.0.2 +* Correctly constructs formulas where references are preceded by operators, e.g. + `-F10` (#26 @cablegui). * No longer misinterprets date formats that use underscores `_` as dates when the underscore is followed by a date-ish character like `M` (#24). diff --git a/src/ref_grammar.h b/src/ref_grammar.h index 71231fe..dd5901e 100644 --- a/src/ref_grammar.h +++ b/src/ref_grammar.h @@ -23,6 +23,23 @@ namespace xlref struct openparen: one< '(' > {}; struct closeparen: one< ')' > {}; + // Operators + struct plusop : one< '+' > {}; + struct minusop : one< '-' > {}; + struct mulop : one< '*' > {}; + struct divop : one< '/' > {}; + struct expop : one< '^' > {}; + struct concatop : one< '&' > {}; + struct intersectop : one< ' ' > {}; + struct rangeop : one< ':' > {}; + struct percentop : one< '%' > {}; + struct gtop : one< '>' > {}; + struct eqop : one< '=' > {}; + struct ltop : one< '<' > {}; + struct neqop : string< '<', '>' > {}; + struct gteop : string< '>', '=' > {}; + struct lteop : string< '<', '=' > {}; + // Text matches two QuoteD (") and anything between, i.e. character and // the surrounding pair of double-quotes. struct QuoteD : one< '"' > {}; @@ -32,10 +49,27 @@ namespace xlref {}; struct Text : seq< QuoteD, DoubleQuotedString, QuoteD > {}; + struct Operator : sor< plusop, + minusop, + mulop, + divop, + expop, + concatop, + intersectop, + rangeop, + percentop, + eqop, + neqop, // Must precede lteop and ltop + gteop, // Must precede gtop + lteop, // Must precede ltop + gtop, + ltop > + {}; + // After attempting a Ref, attempt a Text, otherwise consume everything up to - // the next dollar, comma or parentheses, which are characters that separate - // other tokens. - struct sep: sor< dollar, comma, openparen, closeparen > {}; + // the next operator, dollar, comma or parentheses, which are characters that + // separate other tokens. + struct sep: sor< Operator, dollar, comma, openparen, closeparen > {}; struct notsep: if_then_else< at< sep >, failure, any > {}; struct notseps: plus< notsep > {}; struct Other: sor< sep, notseps > {}; diff --git a/tests/testthat/formulas.xlsx b/tests/testthat/formulas.xlsx index 7eeaf01..62c64ed 100755 Binary files a/tests/testthat/formulas.xlsx and b/tests/testthat/formulas.xlsx differ diff --git a/tests/testthat/test-shared-formula.R b/tests/testthat/test-shared-formula.R index 18507bb..d165eb6 100644 --- a/tests/testthat/test-shared-formula.R +++ b/tests/testthat/test-shared-formula.R @@ -11,5 +11,5 @@ test_that("Shared formulas are propogated correctly", { expect_equal(formulas[239], "E09904.2!A3") formulas <- tidyxl::xlsx_cells("./formulas.xlsx")$formula expect_equal(formulas[3], "N($A2)") + expect_equal(formulas[12], "G4*H4") }) -