tokenizer works
This commit is contained in:
@@ -2,10 +2,12 @@ import express from 'express'
|
|||||||
import { json } from 'body-parser'
|
import { json } from 'body-parser'
|
||||||
import { Sequelize, Op } from 'sequelize'
|
import { Sequelize, Op } from 'sequelize'
|
||||||
import { database, Character, Game, Pick, App } from './db'
|
import { database, Character, Game, Pick, App } from './db'
|
||||||
import { lexr, parseOrderByString, FilterParser } from './tokenizer'
|
import { OrderByParser, FilterParser } from './tokenizer'
|
||||||
|
|
||||||
const app = express()
|
const app = express()
|
||||||
const jsonParser = json()
|
const jsonParser = json()
|
||||||
|
const fp = new FilterParser()
|
||||||
|
const obp = new OrderByParser()
|
||||||
const port = 3001
|
const port = 3001
|
||||||
|
|
||||||
app.get('/', (req, res) => {
|
app.get('/', (req, res) => {
|
||||||
@@ -36,34 +38,19 @@ app.get('/api/game/:gameId', async (req, res) => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
app.post('/api/game', jsonParser, async (req, res) => {
|
app.post('/api/game', jsonParser, async (req, res) => {
|
||||||
console.log(req.body)
|
|
||||||
|
|
||||||
const page = req.body.page || 0
|
const page = req.body.page || 0
|
||||||
const orderBy = req.body.orderBy ? parseOrderByString(req.body.orderBy) : ['id']
|
const orderBy = req.body.orderBy ? obp.parse(req.body.orderBy) : ['id']
|
||||||
const count = req.body.count || 10
|
const count = req.body.count || 10
|
||||||
const filter = req.body.filter || ''
|
const filter = req.body.filter ? fp.parse(req.body.filter) : {}
|
||||||
|
|
||||||
const gameData = await Game.findAll({
|
const gameData = await Game.findAll({
|
||||||
offset: page * count,
|
offset: page * count,
|
||||||
limit: count,
|
limit: count,
|
||||||
order: orderBy,
|
order: orderBy,
|
||||||
where: {
|
where: filter
|
||||||
id: { [Op.eq]: 2 }
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
const pageCount = Math.ceil((await Character.count()) / count)
|
const pageCount = Math.ceil((await Character.count()) / count)
|
||||||
|
|
||||||
let fp = new FilterParser()
|
|
||||||
|
|
||||||
fp.lexer
|
|
||||||
.input(filter)
|
|
||||||
.tokens()
|
|
||||||
.forEach((t) => {
|
|
||||||
console.log(t)
|
|
||||||
})
|
|
||||||
|
|
||||||
console.log(fp.parseFilter(filter))
|
|
||||||
|
|
||||||
res.setHeader('Content-Type', 'application/json')
|
res.setHeader('Content-Type', 'application/json')
|
||||||
res.send({ gameData, pageCount })
|
res.send({ gameData, pageCount })
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,35 +1,31 @@
|
|||||||
import Tokenizr from 'tokenizr'
|
import Tokenizr from 'tokenizr'
|
||||||
import ASTY from 'asty'
|
|
||||||
import { Op } from 'sequelize'
|
import { Op } from 'sequelize'
|
||||||
|
|
||||||
export const lexr = new Tokenizr()
|
export class OrderByParser {
|
||||||
|
lexer = new Tokenizr()
|
||||||
|
|
||||||
lexr.rule(/[AND|OR]/, (ctx, m) => {
|
constructor() {
|
||||||
ctx.accept('conjunction', m[0])
|
this.lexer.rule(/,/, (ctx, m) => {
|
||||||
})
|
ctx.accept('spacer')
|
||||||
|
})
|
||||||
|
|
||||||
export const orderByLexr = new Tokenizr()
|
this.lexer.rule(/ASC|DESC/, (ctx, m) => {
|
||||||
|
ctx.accept('direction', m[0])
|
||||||
|
})
|
||||||
|
|
||||||
orderByLexr.rule(/,/, (ctx, m) => {
|
this.lexer.rule(/[a-zA-Z]+/, (ctx, m) => {
|
||||||
ctx.accept('spacer')
|
ctx.accept('column', m[0])
|
||||||
})
|
})
|
||||||
|
|
||||||
orderByLexr.rule(/ASC|DESC/, (ctx, m) => {
|
this.lexer.rule(/\s/, (ctx, m) => {
|
||||||
ctx.accept('direction', m[0])
|
ctx.ignore()
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
orderByLexr.rule(/[a-zA-Z]+/, (ctx, m) => {
|
parse(orderBy: string) {
|
||||||
ctx.accept('column', m[0])
|
|
||||||
})
|
|
||||||
|
|
||||||
orderByLexr.rule(/\s/, (ctx, m) => {
|
|
||||||
ctx.ignore()
|
|
||||||
})
|
|
||||||
|
|
||||||
export function parseOrderByString(orderBy: string) {
|
|
||||||
const output = []
|
const output = []
|
||||||
let holding = []
|
let holding = []
|
||||||
orderByLexr
|
this.lexer
|
||||||
.input(orderBy)
|
.input(orderBy)
|
||||||
.tokens()
|
.tokens()
|
||||||
.forEach((token) => {
|
.forEach((token) => {
|
||||||
@@ -48,6 +44,7 @@ export function parseOrderByString(orderBy: string) {
|
|||||||
output.push(holding)
|
output.push(holding)
|
||||||
}
|
}
|
||||||
return output
|
return output
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const openGroupRegex = /\(/
|
const openGroupRegex = /\(/
|
||||||
@@ -61,55 +58,47 @@ const opperatorMap = {
|
|||||||
'!=': Op.ne,
|
'!=': Op.ne,
|
||||||
'<=': Op.lte,
|
'<=': Op.lte,
|
||||||
'>=': Op.gte,
|
'>=': Op.gte,
|
||||||
':': Op.like
|
'>': Op.gt,
|
||||||
|
'<': Op.lt,
|
||||||
|
':': Op.like,
|
||||||
|
AND: Op.and,
|
||||||
|
OR: Op.or
|
||||||
}
|
}
|
||||||
|
|
||||||
export class FilterParser {
|
export class FilterParser {
|
||||||
asty: ASTY = new ASTY()
|
lexer: Tokenizr
|
||||||
lexer: Tokenizr = this.createLexer()
|
|
||||||
|
|
||||||
constructor() {}
|
constructor() {
|
||||||
|
this.lexer = new Tokenizr()
|
||||||
|
|
||||||
private createLexer(): Tokenizr {
|
this.lexer.rule(openGroupRegex, (ctx, m) => {
|
||||||
const tkz = new Tokenizr()
|
|
||||||
|
|
||||||
tkz.rule(openGroupRegex, (ctx, m) => {
|
|
||||||
ctx.accept('opengroup')
|
ctx.accept('opengroup')
|
||||||
})
|
})
|
||||||
|
|
||||||
tkz.rule(closeGroupRegex, (ctx, m) => {
|
this.lexer.rule(closeGroupRegex, (ctx, m) => {
|
||||||
ctx.accept('closegroup')
|
ctx.accept('closegroup')
|
||||||
})
|
})
|
||||||
|
|
||||||
tkz.rule(conjunctinoRegex, (ctx, m) => {
|
this.lexer.rule(conjunctinoRegex, (ctx, m) => {
|
||||||
ctx.accept('conjunction', m[0])
|
ctx.accept('conjunction', m[0])
|
||||||
})
|
})
|
||||||
|
|
||||||
tkz.rule(equalityRegex, (ctx, m) => {
|
this.lexer.rule(equalityRegex, (ctx, m) => {
|
||||||
ctx.accept('column', m[1])
|
ctx.accept('column', m[1])
|
||||||
ctx.accept('opperator', m[2])
|
ctx.accept('opperator', m[2])
|
||||||
ctx.accept('value', m[3])
|
ctx.accept('value', m[3])
|
||||||
})
|
})
|
||||||
|
|
||||||
tkz.rule(spacerRegex, (ctx, m) => {
|
this.lexer.rule(spacerRegex, (ctx, m) => {
|
||||||
ctx.ignore()
|
ctx.ignore()
|
||||||
})
|
})
|
||||||
|
|
||||||
return tkz
|
|
||||||
}
|
}
|
||||||
|
|
||||||
parseFilter(filter: string) {
|
parse(filter: string) {
|
||||||
this.lexer.input(filter)
|
this.lexer.input(filter)
|
||||||
console.log(`parsing ${filter}`)
|
|
||||||
this.lexer.begin()
|
|
||||||
this.lexer.tokens().forEach((token) => {
|
|
||||||
console.log(token)
|
|
||||||
})
|
|
||||||
this.lexer.rollback()
|
|
||||||
let block = this.parseBlock('AND')
|
let block = this.parseBlock('AND')
|
||||||
this.lexer.consume('EOF')
|
this.lexer.consume('EOF')
|
||||||
this.lexer.reset()
|
this.lexer.reset()
|
||||||
|
|
||||||
return block
|
return block
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,12 +111,8 @@ export class FilterParser {
|
|||||||
() => this.parseEquality(),
|
() => this.parseEquality(),
|
||||||
() => this.parseGroup(),
|
() => this.parseGroup(),
|
||||||
() => {
|
() => {
|
||||||
|
|
||||||
console.log("Conjunct")
|
|
||||||
|
|
||||||
let conToken = this.lexer.consume('conjunction')
|
let conToken = this.lexer.consume('conjunction')
|
||||||
|
|
||||||
console.log("potato")
|
|
||||||
if (items.length === 1) {
|
if (items.length === 1) {
|
||||||
activeCon = conToken.value
|
activeCon = conToken.value
|
||||||
}
|
}
|
||||||
@@ -137,42 +122,36 @@ export class FilterParser {
|
|||||||
} else {
|
} else {
|
||||||
return this.parseBlock(conToken.value)
|
return this.parseBlock(conToken.value)
|
||||||
}
|
}
|
||||||
}, () => {}
|
},
|
||||||
|
() => this.parseEmpty()
|
||||||
)
|
)
|
||||||
|
|
||||||
if (nextItem === undefined) {
|
if (nextItem === undefined) {
|
||||||
console.log("breaking")
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
items.push(nextItem)
|
items.push(nextItem)
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.asty.create('conjunction').set('type', activeCon).add(items)
|
return { [opperatorMap[activeCon]]: items }
|
||||||
}
|
}
|
||||||
|
|
||||||
private parseConjunction() {}
|
|
||||||
|
|
||||||
private parseEquality() {
|
private parseEquality() {
|
||||||
console.log("doing an equality")
|
|
||||||
let columnToken = this.lexer.consume('column')
|
let columnToken = this.lexer.consume('column')
|
||||||
let opperatorToken = this.lexer.consume('opperator')
|
let opperatorToken = this.lexer.consume('opperator')
|
||||||
let valueToken = this.lexer.consume('value')
|
let valueToken = this.lexer.consume('value')
|
||||||
|
|
||||||
let node = this.asty.create('equality')
|
if (opperatorToken.value === ":") {
|
||||||
|
|
||||||
node.pos(columnToken.line, columnToken.column, columnToken.pos)
|
return {
|
||||||
|
[columnToken.value]: { [opperatorMap[opperatorToken.value]]: `%${valueToken.value.toString()}%` }
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
node.set(columnToken.type, columnToken.value)
|
return {
|
||||||
node.set(opperatorToken.type, opperatorToken.value)
|
[columnToken.value]: { [opperatorMap[opperatorToken.value]]: valueToken.value.toString() }
|
||||||
node.set(valueToken.type, valueToken.value)
|
}
|
||||||
node.set('expression', {
|
}
|
||||||
[columnToken.value]: {
|
|
||||||
[opperatorMap[opperatorToken.value]]: valueToken.value
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return node
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private parseGroup() {
|
private parseGroup() {
|
||||||
@@ -182,4 +161,8 @@ export class FilterParser {
|
|||||||
|
|
||||||
return block
|
return block
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private parseEmpty() {
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user