commonMain.agl.processor.Agl.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of agl-processor-jvm8 Show documentation
Show all versions of agl-processor-jvm8 Show documentation
Dynamic, scan-on-demand, parsing; when a regular expression is just not enough
The newest version!
/**
* Copyright (C) 2018 Dr. David H. Akehurst (http://dr.david.h.akehurst.net)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.akehurst.language.agl.processor
import net.akehurst.language.agl.api.generator.GeneratedLanguageProcessorAbstract
import net.akehurst.language.agl.default.CompletionProviderDefault
import net.akehurst.language.agl.default.SemanticAnalyserDefault
import net.akehurst.language.agl.default.SyntaxAnalyserDefault
import net.akehurst.language.agl.default.TypeModelFromGrammar
import net.akehurst.language.agl.grammar.format.AglFormatterModelDefault
import net.akehurst.language.agl.grammar.grammar.ContextFromGrammar
import net.akehurst.language.agl.grammar.grammar.GrammarContext
import net.akehurst.language.agl.grammar.scopes.ScopeModelAgl
import net.akehurst.language.agl.grammar.style.AglStyleModelDefault
import net.akehurst.language.agl.syntaxAnalyser.*
import net.akehurst.language.api.asm.AsmSimple
import net.akehurst.language.api.grammar.Grammar
import net.akehurst.language.api.processor.*
import net.akehurst.language.typemodel.api.TypeModel
object Agl {
val version: String = BuildConfig.version
val buildStamp: String = BuildConfig.buildStamp
val registry: LanguageRegistry = LanguageRegistryDefault()
fun configurationEmpty(): LanguageProcessorConfiguration =
LanguageProcessorConfigurationDefault(
targetGrammarName = null,
defaultGoalRuleName = null,
typeModelResolver = null,
scopeModelResolver = null,
syntaxAnalyserResolver = null,
semanticAnalyserResolver = null,
formatterResolver = null,
styleResolver = null,
completionProvider = null
)
fun configurationDefault(): LanguageProcessorConfiguration = Agl.configuration {
targetGrammarName(null) //use default
defaultGoalRuleName(null) //use default
typeModelResolver { p -> ProcessResultDefault(TypeModelFromGrammar.create(p.grammar!!), IssueHolder(LanguageProcessorPhase.ALL)) }
scopeModelResolver { p -> ScopeModelAgl.fromString(ContextFromTypeModel(p.grammar!!.qualifiedName, p.typeModel), "") }
syntaxAnalyserResolver { p ->
ProcessResultDefault(
SyntaxAnalyserDefault(p.grammar!!.qualifiedName, p.typeModel, p.scopeModel),
IssueHolder(LanguageProcessorPhase.ALL)
)
}
semanticAnalyserResolver { p -> ProcessResultDefault(SemanticAnalyserDefault(p.scopeModel), IssueHolder(LanguageProcessorPhase.ALL)) }
styleResolver { p -> AglStyleModelDefault.fromString(ContextFromGrammar(p.grammar!!), "") }
formatterResolver { p -> AglFormatterModelDefault.fromString(ContextFromTypeModel(p.grammar!!.qualifiedName, p.typeModel), "") }
completionProvider { p -> ProcessResultDefault(CompletionProviderDefault(p.grammar!!, p.typeModel, p.scopeModel), IssueHolder(LanguageProcessorPhase.ALL)) }
}
/**
* build a set of options for a parser
* (does not set the options, they must be passed as argument)
*/
fun parseOptions(init: ParseOptionsBuilder.() -> Unit): ParseOptions {
val b = ParseOptionsBuilder()
b.init()
return b.build()
}
/**
* build a set of options for a language processor
* (does not set the options, they must be passed as argument)
*/
fun options(init: ProcessOptionsBuilder.() -> Unit): ProcessOptions {
val b = ProcessOptionsBuilder()
b.init()
return b.build()
}
/**
* build a configuration for a language processor
* (does not set the configuration, they must be passed as argument)
*/
fun configuration(
base: LanguageProcessorConfiguration? = null,
init: LanguageProcessorConfigurationBuilder.() -> Unit
): LanguageProcessorConfiguration {
val b = LanguageProcessorConfigurationBuilder(base)
b.init()
return b.build()
}
fun processorFromGrammar(
grammar: Grammar,
configuration: LanguageProcessorConfiguration? = null
): LanguageProcessor {
val config = configuration ?: configurationEmpty()
return LanguageProcessorDefault(grammar, config)
}
/**
* Create a LanguageProcessor from a grammar definition string,
* using default configuration of:
* - targetGrammar = last grammar defined in grammarDefinitionStr
* - defaultGoalRuleName = first non skip goal in targetGrammar
* - syntaxAnalyser = SyntaxAnalyserSimple(TypeModelFromGrammar)
* - semanticAnalyser = SemanticAnalyserSimple
* - formatter = null (TODO)
*
* @param grammarDefinitionStr a string defining the grammar, may contain multiple grammars
* @param aglOptions options to the AGL grammar processor for parsing the grammarDefinitionStr
*/
fun processorFromStringDefault(
grammarDefinitionStr: String,
scopeModelStr: String? = null,
styleModelStr: String? = null,
formatterModelStr: String? = null,
grammarAglOptions: ProcessOptions, GrammarContext>? = null
): LanguageProcessorResult {
val config = Agl.configuration(Agl.configurationDefault()) {
if (null != scopeModelStr) {
scopeModelResolver { p -> ScopeModelAgl.fromString(ContextFromTypeModel(p.grammar!!.qualifiedName, p.typeModel), scopeModelStr) }
}
if (null != styleModelStr) {
styleResolver { p -> AglStyleModelDefault.fromString(ContextFromGrammar(p.grammar!!), styleModelStr) }
}
if (null != formatterModelStr) {
formatterResolver { p -> AglFormatterModelDefault.fromString(ContextFromTypeModel(p.grammar!!.qualifiedName, p.typeModel), formatterModelStr) }
}
}
val proc = processorFromString(grammarDefinitionStr, config, grammarAglOptions)
return proc
}
/**
* Create a LanguageProcessor from a grammar definition string
*
* @param grammarDefinitionStr a string defining the grammar, may contain multiple grammars
* @param configuration options for configuring the created language processor
* @param aglOptions options to the AGL grammar processor
*/
fun processorFromString(
grammarDefinitionStr: String,
configuration: LanguageProcessorConfiguration? = null,
aglOptions: ProcessOptions, GrammarContext>? = null
): LanguageProcessorResult {
return try {
val res = Agl.grammarFromString, GrammarContext>(
grammarDefinitionStr,
aglOptions ?: Agl.registry.agl.grammar.processor!!.optionsDefault()
)
if (null == res.asm || 0 == res.asm!!.size) {
LanguageProcessorResult(null, res.issues)
} else {
val grammar = if (null == configuration?.targetGrammarName) {
res.asm?.lastOrNull() ?: error("Unable to create processor for $grammarDefinitionStr")
} else {
res.asm?.firstOrNull { it.name == configuration.targetGrammarName }
?: error("Unable to find target grammar '${configuration.targetGrammarName}' in $grammarDefinitionStr")
}
val proc = processorFromGrammar(
grammar,
configuration
)
LanguageProcessorResult(proc, res.issues)
}
} catch (e: Throwable) {
throw LanguageProcessorException("Unable to create processor for grammarDefinitionStr: ${e.message}", e)
}
}
fun processorFromGeneratedCode(
generated: GeneratedLanguageProcessorAbstract
): LanguageProcessor {
return LanguageProcessorFromGenerated(generated)
}
fun fromString(
proc: LanguageProcessor,
aglOptions: ProcessOptions,
sentence: String
): ProcessResult {
return proc.process(sentence, aglOptions)
}
fun grammarFromString(sentence: String?, aglOptions: ProcessOptions, GrammarContext>? = null): ProcessResult> {
return if (null == sentence) {
ProcessResultDefault(null, IssueHolder(LanguageProcessorPhase.ALL))
} else {
val res = Agl.registry.agl.grammar.processor!!.process(sentence, aglOptions)
ProcessResultDefault(res.asm ?: emptyList(), res.issues)
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy