All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonMain.agl.processor.Agl.kt Maven / Gradle / Ivy

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