feat(complex-matcher): support numbers (#32)
This commit is contained in:
parent
be4ca0eede
commit
bdddea2e29
@ -1,6 +1,7 @@
|
|||||||
import * as CM from './'
|
import * as CM from './'
|
||||||
|
|
||||||
export const pattern = 'foo !"\\\\ \\"" name:|(wonderwoman batman) hasCape?'
|
export const pattern =
|
||||||
|
'foo !"\\\\ \\"" name:|(wonderwoman batman) hasCape? age:32'
|
||||||
|
|
||||||
export const ast = new CM.And([
|
export const ast = new CM.And([
|
||||||
new CM.String('foo'),
|
new CM.String('foo'),
|
||||||
@ -10,4 +11,5 @@ export const ast = new CM.And([
|
|||||||
new CM.Or([new CM.String('wonderwoman'), new CM.String('batman')])
|
new CM.Or([new CM.String('wonderwoman'), new CM.String('batman')])
|
||||||
),
|
),
|
||||||
new CM.TruthyProperty('hasCape'),
|
new CM.TruthyProperty('hasCape'),
|
||||||
|
new CM.Property('age', new CM.Number(32)),
|
||||||
])
|
])
|
||||||
|
@ -141,6 +141,23 @@ export class Not extends Node {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class NumberNode extends Node {
|
||||||
|
constructor (value) {
|
||||||
|
super()
|
||||||
|
|
||||||
|
this.value = value
|
||||||
|
}
|
||||||
|
|
||||||
|
match (value) {
|
||||||
|
return value === this.value
|
||||||
|
}
|
||||||
|
|
||||||
|
toString () {
|
||||||
|
return String(this.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export { NumberNode as Number }
|
||||||
|
|
||||||
export class Property extends Node {
|
export class Property extends Node {
|
||||||
constructor (name, child) {
|
constructor (name, child) {
|
||||||
super()
|
super()
|
||||||
@ -159,9 +176,10 @@ export class Property extends Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const escapeChar = char => '\\' + char
|
const escapeChar = char => '\\' + char
|
||||||
const formatString = value => isRawString(value)
|
const formatString = value =>
|
||||||
? value
|
Number.isNaN(+value)
|
||||||
: `"${value.replace(/\\|"/g, escapeChar)}"`
|
? isRawString(value) ? value : `"${value.replace(/\\|"/g, escapeChar)}"`
|
||||||
|
: `"${value}"`
|
||||||
|
|
||||||
export class StringNode extends Node {
|
export class StringNode extends Node {
|
||||||
constructor (value) {
|
constructor (value) {
|
||||||
@ -214,14 +232,15 @@ export class TruthyProperty extends Node {
|
|||||||
|
|
||||||
// terms = null || term+
|
// terms = null || term+
|
||||||
// *null = /$/
|
// *null = /$/
|
||||||
// term = ws (and | or | not | property | truthyProperty | string) ws
|
// term = ws (and | or | not | property | truthyProperty | numberOrString) ws
|
||||||
// ws = ' '*
|
// ws = ' '*
|
||||||
// *and = "(" terms ")"
|
// *and = "(" terms ")"
|
||||||
// *or = "|" ws "(" terms ")"
|
// *or = "|" ws "(" terms ")"
|
||||||
// *not = "!" term
|
// *not = "!" term
|
||||||
// *property = string ws ":" term
|
// *property = string ws ":" term
|
||||||
// *truthyProperty = string ws "?"
|
// *truthyProperty = string ws "?"
|
||||||
// *string = quotedString | rawString
|
// numberOrString = string
|
||||||
|
// string = quotedString | rawString
|
||||||
// quotedString = "\"" ( /[^"\]/ | "\\\\" | "\\\"" )+
|
// quotedString = "\"" ( /[^"\]/ | "\\\\" | "\\\"" )+
|
||||||
// rawString = /[a-z0-9-_.]+/i
|
// rawString = /[a-z0-9-_.]+/i
|
||||||
export const parse = invoke(() => {
|
export const parse = invoke(() => {
|
||||||
@ -263,7 +282,7 @@ export const parse = invoke(() => {
|
|||||||
parseNot() ||
|
parseNot() ||
|
||||||
parseProperty() ||
|
parseProperty() ||
|
||||||
parseTruthyProperty() ||
|
parseTruthyProperty() ||
|
||||||
parseString()
|
parseNumberOrString()
|
||||||
if (child) {
|
if (child) {
|
||||||
parseWs()
|
parseWs()
|
||||||
return child
|
return child
|
||||||
@ -308,16 +327,27 @@ export const parse = invoke(() => {
|
|||||||
input[i++] === ':' &&
|
input[i++] === ':' &&
|
||||||
(child = parseTerm())
|
(child = parseTerm())
|
||||||
) {
|
) {
|
||||||
return new Property(name.value, child)
|
return new Property(name, child)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
const parseNumberOrString = () => {
|
||||||
|
let str = parseQuotedString()
|
||||||
|
if (str !== undefined) {
|
||||||
|
return new StringNode(str)
|
||||||
|
}
|
||||||
|
str = parseRawString()
|
||||||
|
if (str !== undefined) {
|
||||||
|
const asNum = +str
|
||||||
|
return Number.isNaN(asNum) ? new StringNode(str) : new NumberNode(asNum)
|
||||||
|
}
|
||||||
|
}
|
||||||
const parseString = () => {
|
const parseString = () => {
|
||||||
let value
|
let value
|
||||||
if (
|
if (
|
||||||
(value = parseQuotedString()) !== undefined ||
|
(value = parseQuotedString()) !== undefined ||
|
||||||
(value = parseRawString()) !== undefined
|
(value = parseRawString()) !== undefined
|
||||||
) {
|
) {
|
||||||
return new StringNode(value)
|
return value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const parseQuotedString = backtrace(() => {
|
const parseQuotedString = backtrace(() => {
|
||||||
@ -350,7 +380,7 @@ export const parse = invoke(() => {
|
|||||||
const parseTruthyProperty = backtrace(() => {
|
const parseTruthyProperty = backtrace(() => {
|
||||||
let name
|
let name
|
||||||
if ((name = parseString()) && parseWs() && input[i++] === '?') {
|
if ((name = parseString()) && parseWs() && input[i++] === '?') {
|
||||||
return new TruthyProperty(name.value)
|
return new TruthyProperty(name)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -24,6 +24,20 @@ describe('parse', () => {
|
|||||||
it('supports an empty string', () => {
|
it('supports an empty string', () => {
|
||||||
expect(parse('')).toEqual(new Null())
|
expect(parse('')).toEqual(new Null())
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('differentiate between numbers and numbers in strings', () => {
|
||||||
|
let node
|
||||||
|
|
||||||
|
node = parse('32')
|
||||||
|
expect(node.match(32)).toBe(true)
|
||||||
|
expect(node.match('32')).toBe(false)
|
||||||
|
expect(node.toString()).toBe('32')
|
||||||
|
|
||||||
|
node = parse('"32"')
|
||||||
|
expect(node.match(32)).toBe(false)
|
||||||
|
expect(node.match('32')).toBe(true)
|
||||||
|
expect(node.toString()).toBe('"32"')
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('setPropertyClause', () => {
|
describe('setPropertyClause', () => {
|
||||||
|
Loading…
Reference in New Issue
Block a user