Skip to content

Commit 81bc07f

Browse files
authored
fix: formula parse for formula begins with ( (#226)
* fix: formula parse brackets * chore: reduce API changes * Rerun tests
1 parent d6811a2 commit 81bc07f

3 files changed

Lines changed: 18 additions & 16 deletions

File tree

packages/core/src/Formula.ts

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -180,28 +180,18 @@ export function evaluate<T, V extends boolean | null = boolean>(
180180
}
181181

182182
export function parse(q?: string): Formula<string, null> | undefined {
183-
if (!q) {
184-
return
185-
}
186-
187-
let parsed
188183
try {
189-
// eslint-disable-next-line
190-
parsed = _parse(q)
191-
} catch {
192-
if (q && q.startsWith('(')) {
193-
return
194-
} else {
195-
return parse('(' + q + ')')
184+
if (q) {
185+
// eslint-disable-next-line
186+
return fromJSON(_parse(`(${q})`) as Serialized)
196187
}
197-
}
198-
199-
return fromJSON(parsed as any)
188+
} catch {}
200189
}
201190

202191
type Serialized<X = never> =
203192
| { and: Serialized[] }
204193
| { or: Serialized[] }
194+
| { inner: Serialized }
205195
| { property: string; value: boolean | X }
206196
| Record<string, boolean | X>
207197

@@ -210,6 +200,8 @@ export function fromJSON(json: Serialized): Formula<string, null> {
210200
return and<string, null>(...json.and.map(fromJSON))
211201
} else if ('or' in json && typeof json.or === 'object') {
212202
return or<string, null>(...json.or.map(fromJSON))
203+
} else if ('inner' in json && typeof json.inner === 'object') {
204+
return fromJSON(json.inner)
213205
} else if ('property' in json && typeof json.property === 'string') {
214206
return atom<string, null>(json.property, json.value)
215207
}

packages/core/src/Formula/Grammar.pegjs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Formula "formula" = And / Or / Atom
1+
Formula "formula" = And / Or / Wrapped / Atom
22

33
_ "whitespace" = [ \t\n\r]*
44

@@ -10,6 +10,10 @@ Or = _ "(" _ head:Formula tail:(_ Disjunction _ Formula)+ _ ")" _ {
1010
return { or: [head].concat(tail.map((item: unknown[]) => item[3])) }
1111
}
1212

13+
Wrapped = _ "(" _ inner:Formula _ ")" _ {
14+
return { inner }
15+
}
16+
1317
Atom = mod:Modifier? _ prop:Property {
1418
let value;
1519
if (mod === '?') {

packages/core/test/Formula.test.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,12 @@ describe('parsing', () => {
190190
expect(parse()).toBeUndefined()
191191
expect(parse('')).toBeUndefined()
192192
})
193+
194+
it('resolves #226', () => {
195+
expect(parse('(T1 | T2) & T3')).toEqual(
196+
and(or(atom('T1'), atom('T2')), atom('T3')),
197+
)
198+
})
193199
})
194200

195201
describe('serialization', () => {

0 commit comments

Comments
 (0)