Skip to content

Instantly share code, notes, and snippets.

@pward123
Created August 26, 2016 16:09
Show Gist options
  • Save pward123/0555e4a6ab1b21be318db34d6a232032 to your computer and use it in GitHub Desktop.
Save pward123/0555e4a6ab1b21be318db34d6a232032 to your computer and use it in GitHub Desktop.
Jison Custom Scanner
import {Parser} from 'jison'
// tokens
const EOL = 'EOL' // End of line
const EOR = 'EOR' // End of record
const LEFT = 'x'
const TOP = 'y'
const WIDTH = 'c'
const HEIGHT = 'r'
const INVALID = 'INVALID'
const NUMBER = 'NUMBER'
// regex
const rxDigit = /[0-9]/
const rxSpace = /\s/
const rxLeft = /[xX]/
const rxTop = /[yY]/
const rxWidth = /[cC]/
const rxHeight = /[rR]/
const rxEOR = /,/
class LayoutScanner {
constructor() {
this._text = ''
this.yytext = ''
this.yylloc = this.yyloc = {
first_column: 0, // eslint-disable-line camelcase
first_line : 1, // eslint-disable-line camelcase
last_line : 1, // eslint-disable-line camelcase
last_column : 0, // eslint-disable-line camelcase
}
}
setInput(text) {
this._text = text
}
lex() {
if (this._text === '') {
return EOL
}
// Consume a single character and increment our column numbers.
let c = this._text.charAt(0)
this._text = this._text.substring(1)
// Ignore any whitespace
while (rxSpace.test(c)) {
if (this._text === '') {
return EOL
}
c = this._text.charAt(0)
this._text = this._text.substring(1)
}
this.yytext = c
this.yyloc.first_column++
this.yyloc.last_column++
// Numbers
if (rxDigit.test(c)) {
c = this._text.charAt(0)
while (rxDigit.test(c)) {
this._text = this._text.substring(1)
this.yytext += c
this.yyloc.last_column++
c = this._text.charAt(0)
}
return NUMBER
}
if (rxLeft.test(c)) {
return LEFT
}
if (rxTop.test(c)) {
return TOP
}
if (rxWidth.test(c)) {
return WIDTH
}
if (rxHeight.test(c)) {
return HEIGHT
}
if (rxEOR.test(c)) {
return EOR
}
console.log(`Error at ${this.yyloc.first_column}`)
return INVALID
}
}
const grammar = String.raw`
%%
expressions
: DISPLAY_LIST EOL
{return $1;}
;
DISPLAY_LIST
: DISPLAY
{$$ = [$1];}
| DISPLAY_LIST EOR DISPLAY
{$1.push($3); $$ = $1;}
;
DISPLAY
: x NUMBER y NUMBER c NUMBER r NUMBER
{$$ = {x: $2, y: $4, c: $6, r: $8};}
| x NUMBER y NUMBER c NUMBER
{$$ = {x: $2, y: $4, c: $6, r: 1};}
| x NUMBER y NUMBER r NUMBER
{$$ = {x: $2, y: $4, c: 1, r: $6};}
| x NUMBER y NUMBER
{$$ = {x: $2, y: $4, c: 1, r: 1};}
;
`
const parser = new Parser(grammar)
parser.lexer = new LayoutScanner()
try {
const displays = parser.parse('x 1 y 1 c 2 r 2 , x3y1, x3y2, x1y1, x1y2, x1y3')
console.log(JSON.stringify(displays))
} catch (e) {
console.log(e)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment