Skip to content

Commit

Permalink
feat: ✨ handle reserver identifiers (#8)
Browse files Browse the repository at this point in the history
  • Loading branch information
ChromeGG authored Dec 7, 2023
1 parent eb5ef8e commit 8d92443
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 1 deletion.
1 change: 1 addition & 0 deletions src/cst-definitions.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export interface AtomicExpressionCstNode extends CstNode {
export type AtomicExpressionCstChildren = {
Integer?: IToken[];
identifier?: IdentifierCstNode[];
ReservedIdentifiers?: IToken[];
};

export interface ICstNodeVisitor<IN, OUT> extends ICstVisitor<IN, OUT> {
Expand Down
16 changes: 16 additions & 0 deletions src/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { expect, describe, it } from 'vitest'

import { parse } from './index.js'
import { reservedIdentifiers } from './tokens.js'

describe('specification of CEL', () => {
describe('comparisons', () => {
Expand Down Expand Up @@ -62,4 +63,19 @@ describe('specification of CEL', () => {
expect(result).toThrow(`Identifier "a" not found in context: {"b":2}`)
})
})

describe('reserved identifiers', () => {
it.each(reservedIdentifiers)(
'should throw if reserved identifier "%s" is used',
(identifier) => {
const expr = `${identifier} < 1`

const result = () => parse(expr)

expect(result).toThrow(
`Detected reserved identifier. This is not allowed`
)
}
)
})
})
2 changes: 2 additions & 0 deletions src/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
StringLiteral,
GreaterOrEqualThan,
LessOrEqualThan,
ReservedIdentifiers,
} from './tokens.js'

export class CelParser extends CstParser {
Expand Down Expand Up @@ -65,6 +66,7 @@ export class CelParser extends CstParser {
this.OR([
{ ALT: () => this.CONSUME(Integer) },
{ ALT: () => this.SUBRULE(this.identifier) },
{ ALT: () => this.CONSUME(ReservedIdentifiers) },
])
})
}
30 changes: 29 additions & 1 deletion src/tokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,41 @@ export const Integer = createToken({ name: 'Integer', pattern: /0|[1-9]\d*/ })
export const Plus = createToken({ name: 'Plus', pattern: /\+/ })
export const Minus = createToken({ name: 'Minus', pattern: /-/ })

export const reservedIdentifiers = [
'as',
'break',
'const',
'continue',
'else',
'for',
'function',
'if',
'import',
'let',
'loop',
'package',
'namespace',
'return',
'var',
'void',
'while',
]

const reserverIdentifiersPattern = reservedIdentifiers.join('|')

export const ReservedIdentifiers = createToken({
name: 'ReservedIdentifiers',
pattern: new RegExp(reserverIdentifiersPattern),
})

// The order of tokens is important
export const allTokens = [
WhiteSpace,
OpenParenthesis,
CloseParenthesis,
Equals,
// keywords must be before Identifier
// ReservedIdentifiers must be before Identifiers
ReservedIdentifiers,
Identifier,
Dot,
OpenBracket,
Expand Down
4 changes: 4 additions & 0 deletions src/visitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ export class CelVisitor
return this.visit(ctx.identifier)
}

if (ctx.ReservedIdentifiers) {
throw new Error('Detected reserved identifier. This is not allowed')
}

throw new Error('Atomic expression not recognized')
}

Expand Down

0 comments on commit 8d92443

Please sign in to comment.