Created
December 27, 2017 18:59
-
-
Save mnn/f2729317b68436d550f918f2566c7192 to your computer and use it in GitHub Desktop.
QML parser
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* QML parser | |
* author: monnef | |
* license: MIT | |
*/ | |
import fs = require('fs'); | |
import * as P from 'parsimmon'; | |
class ImportToken { | |
type = 'import'; | |
constructor(public value: String) { } | |
} | |
class Entity { | |
type = 'entity'; | |
constructor(public id: String, public contents: (Entity | Property)[]) { } | |
} | |
class Property { | |
type = 'property'; | |
constructor(public key: string, public value: string) { } | |
} | |
type ParseResult = [ | |
ImportToken[], | |
Entity[] | |
]; | |
export class QmlParser { | |
static readonly regexGenProperty = () => /([a-zA-Z_0-9]+): (.*)$/m; | |
static readonly lang = P.createLanguage({ | |
Lang: r => P.seq( | |
P.sepBy(r.Import, r._).trim(r._), | |
P.sepBy(r.Entity, r._) | |
), | |
Import: r => P.regex(/import(.*)$/m, 1).map(x => new ImportToken(x)), | |
EntityId: r => P.regex(/[a-zA-Z]+/), | |
Property: r => P.regex(QmlParser.regexGenProperty()) | |
.map(x => { | |
const chopped = <string[]>QmlParser.regexGenProperty().exec(x); | |
return new Property(chopped[1], chopped[2]); | |
}), | |
Entity: r => P.seqMap( | |
r.EntityId.trim(r._), | |
P.string('{').trim(r._), | |
P.sepBy(P.alt( | |
r.Property, | |
r.Entity | |
), r._), | |
P.string('}').trim(r._), | |
(id, start, body, end) => { | |
return new Entity(id, body); | |
} | |
), | |
_: r => P.optWhitespace | |
}); | |
static parse(input: string): ParseResult { | |
return QmlParser.lang.Lang.tryParse(input); | |
}; | |
static parseFile(fileName: string): ParseResult { | |
const qml = fs.readFileSync(fileName).toString(); | |
return QmlParser.parse(qml); | |
}; | |
} | |
const qmlDir = 'qml/'; | |
const outDir = 'parsedQml/'; | |
fs.readdirSync(qmlDir).forEach(file => { | |
let result = QmlParser.parseFile(qmlDir + file); | |
// console.log(JSON.stringify(result, null, 2)); | |
fs.writeFileSync(outDir + file.slice(0, -3) + 'json', JSON.stringify(result, null, 2)); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment