Package org.sablecc.sablecc.codegeneration

Source Code of org.sablecc.sablecc.codegeneration.TransformationGeneration$ListDescriptor

/* This file is part of SableCC ( http://sablecc.org ).
*
* See the NOTICE file distributed with this work for copyright information.
*
* 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 org.sablecc.sablecc.codegeneration;

import static org.sablecc.util.CamelCase.*;

import java.math.*;
import java.util.*;

import org.sablecc.exception.*;
import org.sablecc.sablecc.codegeneration.java.macro.*;
import org.sablecc.sablecc.core.*;
import org.sablecc.sablecc.core.interfaces.*;
import org.sablecc.sablecc.grammar.*;
import org.sablecc.sablecc.grammar.Element.ProductionElement;
import org.sablecc.sablecc.grammar.Element.TokenElement;
import org.sablecc.sablecc.grammar.interfaces.*;
import org.sablecc.sablecc.grammar.transformation.*;
import org.sablecc.sablecc.oldlrautomaton.*;
import org.sablecc.util.Type.SimpleType.AlternatedType;
import org.sablecc.util.Type.SimpleType.HomogeneousType;
import org.sablecc.util.Type.SimpleType.SeparatedType;

public class TransformationGeneration
        implements ITransformationVisitor {

    private final Stack<Object> macroStack = new Stack<Object>();

    private final Stack<ListDescriptor> listStack = new Stack<ListDescriptor>();

    private final OldAlternative reducedAlternative;

    private final Grammar grammar;

    private Map<String, BigInteger> nameToVarNameMap = new HashMap<String, BigInteger>();

    private final Map<IReferencable, String> alternativeToCamelFullName;

    TransformationGeneration(
            Grammar grammar,
            OldAlternative reducedAlternative,
            MReduceDecision reduceDecision,
            Map<IReferencable, String> alternativeToCamelFullName) {

        this.grammar = grammar;
        this.reducedAlternative = reducedAlternative;
        this.macroStack.push(reduceDecision);
        this.alternativeToCamelFullName = alternativeToCamelFullName;

    }

    private String getNextVarId(
            String base) {

        BigInteger varCount = this.nameToVarNameMap.get(base);

        if (varCount == null) {
            if (base == "") {
                this.nameToVarNameMap.put(base, BigInteger.ONE);
                return to_camelCase("$" + BigInteger.ONE);
            }
            else {
                this.nameToVarNameMap.put(base, BigInteger.ZERO);
                return to_camelCase(base);
            }

        }
        else {
            varCount.add(BigInteger.ONE);
            this.nameToVarNameMap.put(base, varCount);
            return to_camelCase(base + "$" + varCount);
        }
    }

    @Override
    public void visitNewElement(
            SAlternativeTransformationElement.NewElement node) {

        String alt_CamelCase = this.alternativeToCamelFullName.get(node
                .getAlternative());

        String elementName = getNextVarId(alt_CamelCase);

        Object currentMacro = this.macroStack.peek();

        MNewTreeClass newMacro;

        if (currentMacro instanceof MReduceDecision) {
            newMacro = ((MReduceDecision) currentMacro).newNewTreeClass(
                    alt_CamelCase, elementName);
        }
        else if (currentMacro instanceof MNewTreeClass) {
            newMacro = ((MNewTreeClass) currentMacro).newNewTreeClass(
                    alt_CamelCase, elementName);
        }
        else {
            throw new InternalException("Unhandle " + currentMacro.getClass());
        }

        this.macroStack.push(newMacro);

        for (SAlternativeTransformationElement e : node.getElements()) {
            e.apply(this);
        }

        this.macroStack.pop();

        if (currentMacro instanceof MReduceDecision) {
            ((MReduceDecision) currentMacro).newAddNToForest(elementName);
        }
        else if (currentMacro instanceof MNewTreeClass) {
            newMacro.newNewParameter(elementName);
        }
        else {
            throw new InternalException("Unhandle " + currentMacro.getClass());
        }

    }

    @Override
    public void visitReferenceElement(
            SAlternativeTransformationElement.ReferenceElement node) {

        IElement reference = node.getTargetReference();
        Object currentMacro = this.macroStack.peek();

        String elementName = to_camelCase(this.grammar.getSimplifiedGrammar()
                .getOldElement(node.getOriginReference()).getName());

        if (reference instanceof TokenElement) {

            OldElement matchedElement = this.reducedAlternative
                    .getElement((TokenElement) reference);

            if (currentMacro instanceof MNewTreeClass) {
                ((MNewTreeClass) currentMacro).newNormalParameter(
                        to_CamelCase(matchedElement.getTypeName()),
                        elementName, "0");
            }
            else if (currentMacro instanceof MReduceDecision) {
                ((MReduceDecision) currentMacro).newAddPopToForest(elementName,
                        "0");
            }
            else {
                throw new InternalException("Unhandled "
                        + currentMacro.getClass());
            }

        }
        else if (reference instanceof ProductionElement) {
            OldElement matchedElement = this.reducedAlternative
                    .getElement((ProductionElement) reference);

            if (currentMacro instanceof MNewTreeClass) {
                ((MNewTreeClass) currentMacro).newNormalParameter(
                        to_CamelCase(matchedElement.getTypeName()),
                        elementName, "0");
            }
            else if (currentMacro instanceof MReduceDecision) {
                ((MReduceDecision) currentMacro).newAddPopToForest(elementName,
                        "0");
            }
            else {
                throw new InternalException("Unhandled "
                        + currentMacro.getClass());
            }
        }
        else if (reference instanceof SProductionTransformationElement) {

            if (reference instanceof SProductionTransformationElement.NormalElement) {
                SProductionTransformationElement.NormalElement normalElement = (SProductionTransformationElement.NormalElement) reference;

                if (normalElement.getCoreReference() instanceof Tree.TreeProduction) {
                    String prodCamelCaseType = ((Tree.TreeProduction) normalElement
                            .getCoreReference()).getName_CamelCase();

                    if (currentMacro instanceof MNewTreeClass) {
                        ((MNewTreeClass) currentMacro).newNormalParameter(
                                prodCamelCaseType, elementName,
                                normalElement.getIndex() + "");
                    }
                    else if (currentMacro instanceof MReduceDecision) {
                        ((MReduceDecision) currentMacro)
                                .newAddLToForest(elementName);
                    }
                    else {
                        throw new InternalException("Unhandled "
                                + currentMacro.getClass());
                    }
                }

            }
            else if (reference instanceof SProductionTransformationElement.SeparatedElement) {
                SProductionTransformationElement.SeparatedElement separatedElement = (SProductionTransformationElement.SeparatedElement) reference;

                String elementLeftName = computeElementType(separatedElement
                        .getLeftTreeReference());
                String elementRightName = computeElementType(separatedElement
                        .getRightTreeReference());

                if (currentMacro instanceof MNewTreeClass) {
                    ((MNewTreeClass) currentMacro).newSeparatedParameter(
                            elementLeftName,
                            elementRightName,
                            elementName,
                            ((SProductionTransformationElement) reference)
                                    .getIndex() + "");
                }
                else if (currentMacro instanceof MReduceDecision) {

                    ((MReduceDecision) currentMacro)
                            .newAddLToForest(elementName);
                }
                else {
                    throw new InternalException("Unhandled "
                            + currentMacro.getClass());
                }

            }
            else if (reference instanceof SProductionTransformationElement.AlternatedElement) {
                SProductionTransformationElement.AlternatedElement alternatedElement = (SProductionTransformationElement.AlternatedElement) reference;

                String elementLeftName = computeElementType(alternatedElement
                        .getLeftTreeReference());
                String elementRightName = computeElementType(alternatedElement
                        .getRightTreeReference());

                if (currentMacro instanceof MNewTreeClass) {
                    ((MNewTreeClass) currentMacro).newAlternatedParameter(
                            elementLeftName,
                            elementRightName,
                            elementName,
                            ((SProductionTransformationElement) reference)
                                    .getIndex() + "");
                }
                else if (currentMacro instanceof MReduceDecision) {

                    ((MReduceDecision) currentMacro)
                            .newAddLToForest(elementName);
                }
                else {
                    throw new InternalException("Unhandled "
                            + currentMacro.getClass());
                }

            }
            else {
                throw new InternalException("Unhandled "
                        + currentMacro.getClass());
            }

        }

    }

    private String computeElementType(
            IReferencable reference) {

        if (reference instanceof Tree.TreeProduction) {
            return ((Tree.TreeProduction) reference).getName_CamelCase();
        }
        else if (reference instanceof LexerExpression.NamedExpression) {
            return ((LexerExpression.NamedExpression) reference)
                    .getName_CamelCase();
        }
        else if (reference instanceof LexerExpression.InlineExpression) {
            return ((LexerExpression.InlineExpression) reference)
                    .getInternalName_CamelCase();
        }
        else {
            throw new InternalException("Unhandled reference type");
        }
    }

    private String computeListType(
            String typeName) {

        INameDeclaration nameDeclaration = this.grammar
                .getGlobalReference(typeName);

        if (nameDeclaration instanceof LexerExpression.NamedExpression) {
            LexerExpression.NamedExpression namedToken = (LexerExpression.NamedExpression) nameDeclaration;
            return namedToken.getName_CamelCase();
        }
        else if (nameDeclaration instanceof LexerExpression.InlineExpression) {
            LexerExpression.InlineExpression inlineToken = (LexerExpression.InlineExpression) nameDeclaration;
            return inlineToken.getInternalName_CamelCase();
        }
        else if (nameDeclaration instanceof Parser.ParserProduction) {
            return to_CamelCase(((Parser.ParserProduction) nameDeclaration)
                    .getName());
        }
        else {
            throw new InternalException("Unhandle "
                    + nameDeclaration.getClass());
        }
    }

    @Override
    public void visitListElement(
            SAlternativeTransformationElement.ListElement node) {

        Object currentMacro = this.macroStack.peek();
        String listName = getNextVarId("");
        MNewList newList;

        if (currentMacro instanceof MReduceDecision) {
            newList = ((MReduceDecision) currentMacro).newNewList(listName);
        }
        else if (currentMacro instanceof MNewTreeClass) {
            newList = ((MNewTreeClass) currentMacro).newNewList(listName);
        }
        else {
            throw new InternalException("Unhandle " + currentMacro.getClass());
        }

        if (node.getType() instanceof HomogeneousType) {

            HomogeneousType type = (HomogeneousType) node.getType();

            String listType = computeListType(type.getName());

            newList.newNormalDeclaration(listType);
            this.listStack.push(new NormalListDescriptor(listName, listType));

        }
        else {
            String leftListType;
            String rightListType;

            if (node.getType() instanceof SeparatedType) {
                SeparatedType type = (SeparatedType) node.getType();

                leftListType = computeListType(type.getLeftElementName());
                rightListType = computeListType(type.getRightElementName());

                newList.newSeparatedDeclaration(leftListType, rightListType);

                this.listStack.push(new DoubleListDescriptor(
                        DoubleListDescriptor.Type.SEPARATED, listName,
                        leftListType, rightListType));
            }
            else if (node.getType() instanceof AlternatedType) {
                AlternatedType type = (AlternatedType) node.getType();

                leftListType = computeListType(type.getLeftElementName());
                rightListType = computeListType(type.getRightElementName());

                newList.newAlternatedDeclaration(leftListType, rightListType);

                this.listStack.push(new DoubleListDescriptor(
                        DoubleListDescriptor.Type.ALTERNATED, listName,
                        leftListType, rightListType));
            }
            else {
                throw new InternalException("Unhandle type " + node.getClass());
            }

        }

        this.macroStack.push(newList);

        for (SAlternativeTransformationListElement e : node.getElements()) {
            e.apply(this);
        }

        this.listStack.pop();
        newList = (MNewList) this.macroStack.pop();

        newList.newStringParameter(node.getType().getCardinality()
                .getLowerBound().getValue()
                + "");

        if (!node.getType().getCardinality().upperBoundIsInfinite()) {
            newList.newStringParameter(node.getType().getCardinality()
                    .getUpperBound().getValue()
                    + "");
        }

        if (currentMacro instanceof MReduceDecision) {
            ((MReduceDecision) currentMacro).newAddNToForest(listName);
        }
        else if (currentMacro instanceof MNewTreeClass) {
            ((MNewTreeClass) currentMacro).newNewParameter(listName);
        }
        else {
            throw new InternalException("Unhandled " + currentMacro.getClass());
        }

    }

    @Override
    public void visitNullElement(
            SAlternativeTransformationElement.NullElement node) {

        Object currentMacro = this.macroStack.peek();

        if (currentMacro instanceof MReduceDecision) {

            ((MReduceDecision) currentMacro).newAddNullToForest();

        }
        else if (currentMacro instanceof MNewTreeClass) {
            ((MNewTreeClass) currentMacro).newNullParameter();
        }
        else {
            throw new InternalException("Unhandled " + currentMacro.getClass());
        }

    }

    @Override
    public void visitReferenceListElement(
            SAlternativeTransformationListElement.ReferenceElement node) {

        MNewList list = (MNewList) this.macroStack.peek();

        if (node.getTargetReference() instanceof Element) {
            String elementName = this.reducedAlternative.getElement(
                    (Element) node.getTargetReference()).getName();
            String elementType = to_CamelCase(this.reducedAlternative
                    .getElement((Element) node.getTargetReference())
                    .getTypeName());

            if (this.listStack.peek() instanceof NormalListDescriptor) {
                list.newAddPopElement(this.listStack.peek().getListName(),
                        elementName, elementType, "0");
            }
            else {
                DoubleListDescriptor listDescriptor = (DoubleListDescriptor) this.listStack
                        .peek();

                if (elementType.equals(listDescriptor.getLeftListType())) {
                    list.newAddPopElementLeft(this.listStack.peek()
                            .getListName(), elementName, elementType, "0");
                }
                else {
                    list.newAddPopElementRight(this.listStack.peek()
                            .getListName(), elementName, elementType, "0");
                }
            }

        }
        else if (node.getTargetReference() instanceof SProductionTransformationElement) {

            SProductionTransformationElement reference = (SProductionTransformationElement) node
                    .getTargetReference();

            String elementName = this.grammar.getSimplifiedGrammar()
                    .getOldElement(node.getOriginReference()).getName();
            String listName = this.listStack.peek().getListName();
            String elementType;

            if (this.listStack.peek() instanceof NormalListDescriptor) {
                elementType = ((NormalListDescriptor) this.listStack.peek())
                        .getListType();
            }
            else {

                if (reference instanceof SProductionTransformationElement.NormalElement) {

                    SProductionTransformationElement.NormalElement normalElement = (SProductionTransformationElement.NormalElement) reference;

                    if (normalElement.getCoreReference() instanceof Tree.TreeProduction) {
                        elementType = ((Tree.TreeProduction) normalElement
                                .getCoreReference()).getName_CamelCase();

                    }
                    else if (normalElement.getCoreReference() instanceof LexerExpression.NamedExpression) {
                        elementType = ((LexerExpression.NamedExpression) normalElement
                                .getCoreReference()).getName_CamelCase();
                    }
                    else if (normalElement.getCoreReference() instanceof LexerExpression.InlineExpression) {
                        elementType = ((LexerExpression.InlineExpression) normalElement
                                .getCoreReference())
                                .getInternalName_CamelCase();
                    }
                    else {
                        throw new InternalException("unhandle case");
                    }
                }
                else {
                    throw new InternalException("Unexpected reference "
                            + reference.getClass());
                }
            }

            list.newAddPopElement(listName, elementName, elementType,
                    reference.getIndex() + "");

        }
        else {
            throw new InternalException("Unhandled " + node.getClass());

        }

    }

    @Override
    public void visitNewListElement(
            SAlternativeTransformationListElement.NewElement node) {

        String alt_CamelCase = this.alternativeToCamelFullName.get(node
                .getAlternative());

        String elementName = getNextVarId(alt_CamelCase);

        MNewList list = (MNewList) this.macroStack.peek();
        MNewTreeClass newMacro = list.newNewTreeClass(alt_CamelCase,
                elementName);

        this.macroStack.push(newMacro);

        for (SAlternativeTransformationElement e : node.getElements()) {
            e.apply(this);
        }

        this.macroStack.pop();

        list.newAddNewElement(this.listStack.peek().getListName(), elementName);

    }

    @Override
    public void visitNormalListListElement(
            SAlternativeTransformationListElement.NormalListElement node) {

        MNewList list = (MNewList) this.macroStack.peek();

        String elementName = to_camelCase(this.grammar.getSimplifiedGrammar()
                .getOldElement(node.getOriginReference()).getName());

        if (this.listStack.peek() instanceof NormalListDescriptor) {

            if (node.getTargetReference() instanceof SProductionTransformationElement.NormalElement) {
                String elementType = ((NormalListDescriptor) this.listStack
                        .peek()).getListType();

                list.newAddPopList(this.listStack.peek().getListName(),
                        elementName, elementType, node.getTargetReference()
                                .getIndex() + "");

            }
            else {
                throw new InternalException("Unexpected case");
            }
        }
        else {
            DoubleListDescriptor listDescriptor = (DoubleListDescriptor) this.listStack
                    .peek();

            if (node.getTargetReference() instanceof SProductionTransformationElement.SeparatedElement) {

                SProductionTransformationElement.SeparatedElement separatedElement = (SProductionTransformationElement.SeparatedElement) node
                        .getTargetReference();

                String leftElementTransformationName = computeElementType(separatedElement
                        .getLeftTreeReference());

                if (leftElementTransformationName.equals(listDescriptor
                        .getLeftListType())) {
                    list.newAddPopSeparatedList(listDescriptor.getListName(),
                            elementName, listDescriptor.getLeftListType(),
                            listDescriptor.getRightListType(), node
                                    .getTargetReference().getIndex() + "");

                }
                else {
                    list.newAddPopReverseSeparatedList(
                            listDescriptor.getListName(), elementName,
                            listDescriptor.getRightListType(),
                            listDescriptor.getLeftListType(), node
                                    .getTargetReference().getIndex() + "");
                }

            }
            else if (node.getTargetReference() instanceof SProductionTransformationElement.AlternatedElement) {

                SProductionTransformationElement.AlternatedElement alternatedElement = (SProductionTransformationElement.AlternatedElement) node
                        .getTargetReference();

                String leftElementTransformationName = computeElementType(alternatedElement
                        .getLeftTreeReference());

                if (leftElementTransformationName.equals(listDescriptor
                        .getLeftListType())) {
                    list.newAddPopAlternatedList(listDescriptor.getListName(),
                            elementName, listDescriptor.getLeftListType(),
                            listDescriptor.getRightListType(), node
                                    .getTargetReference().getIndex() + "");

                }
                else {
                    list.newAddPopReverseAlternatedList(
                            listDescriptor.getListName(), elementName,
                            listDescriptor.getRightListType(),
                            listDescriptor.getLeftListType(), node
                                    .getTargetReference().getIndex() + "");

                }

            }
            else {
                throw new InternalException("Unexpected case");
            }

        }

    }

    @Override
    public void visitLeftListListElement(
            SAlternativeTransformationListElement.LeftListElement node) {

        MNewList list = (MNewList) this.macroStack.peek();

        if (this.listStack.peek() instanceof NormalListDescriptor) {

            String leftElementType;
            String rightElementType;
            String elementName = to_camelCase(this.grammar
                    .getSimplifiedGrammar()
                    .getOldElement(node.getOriginReference()).getName());

            if (node.getTargetReference() instanceof SProductionTransformationElement.AlternatedElement) {
                SProductionTransformationElement.AlternatedElement transformationElement = (SProductionTransformationElement.AlternatedElement) node
                        .getTargetReference();

                leftElementType = computeElementType(transformationElement
                        .getLeftTreeReference());
                rightElementType = computeElementType(transformationElement
                        .getRightTreeReference());

                MAddPopAlternatedList mAddPopAlternatedList = list
                        .newAddPopAlternatedList(this.listStack.peek()
                                .getListName(), elementName, leftElementType,
                                rightElementType,
                                transformationElement.getIndex() + "");
                mAddPopAlternatedList.newGetLeft();
            }
            else if (node.getTargetReference() instanceof SProductionTransformationElement.SeparatedElement) {
                SProductionTransformationElement.SeparatedElement transformationElement = (SProductionTransformationElement.SeparatedElement) node
                        .getTargetReference();

                leftElementType = computeElementType(transformationElement
                        .getLeftTreeReference());
                rightElementType = computeElementType(transformationElement
                        .getRightTreeReference());

                MAddPopSeparatedList mAddPopSeparatedList = list
                        .newAddPopSeparatedList(this.listStack.peek()
                                .getListName(), elementName, leftElementType,
                                rightElementType,
                                transformationElement.getIndex() + "");
                mAddPopSeparatedList.newGetLeft();
            }
            else {
                throw new InternalException("Unexpected case");
            }
        }

    }

    @Override
    public void visitRightListListElement(
            SAlternativeTransformationListElement.RightListElement node) {

        MNewList list = (MNewList) this.macroStack.peek();

        if (this.listStack.peek() instanceof NormalListDescriptor) {

            String leftElementType;
            String rightElementType;
            String elementName = to_camelCase(this.grammar
                    .getSimplifiedGrammar()
                    .getOldElement(node.getOriginReference()).getName());

            if (node.getTargetReference() instanceof SProductionTransformationElement.AlternatedElement) {
                SProductionTransformationElement.AlternatedElement transformationElement = (SProductionTransformationElement.AlternatedElement) node
                        .getTargetReference();

                leftElementType = computeElementType(transformationElement
                        .getLeftTreeReference());
                rightElementType = computeElementType(transformationElement
                        .getRightTreeReference());

                MAddPopAlternatedList mAddPopAlternatedList = list
                        .newAddPopAlternatedList(this.listStack.peek()
                                .getListName(), elementName, leftElementType,
                                rightElementType,
                                transformationElement.getIndex() + "");
                mAddPopAlternatedList.newGetRight();
            }
            else if (node.getTargetReference() instanceof SProductionTransformationElement.SeparatedElement) {
                SProductionTransformationElement.SeparatedElement transformationElement = (SProductionTransformationElement.SeparatedElement) node
                        .getTargetReference();

                leftElementType = computeElementType(transformationElement
                        .getLeftTreeReference());
                rightElementType = computeElementType(transformationElement
                        .getRightTreeReference());

                MAddPopSeparatedList mAddPopSeparatedList = list
                        .newAddPopSeparatedList(this.listStack.peek()
                                .getListName(), elementName, leftElementType,
                                rightElementType,
                                transformationElement.getIndex() + "");
                mAddPopSeparatedList.newGetRight();
            }
            else {
                throw new InternalException("Unexpected case");
            }
        }

    }

    private static abstract class ListDescriptor {

        private final String listName;

        public ListDescriptor(
                String listName) {

            this.listName = listName;
        }

        public String getListName() {

            return this.listName;
        }
    }

    private static class NormalListDescriptor
            extends ListDescriptor {

        private final String listType;

        public NormalListDescriptor(
                String listName,
                String listType) {

            super(listName);
            this.listType = listType;
        }

        public String getListType() {

            return this.listType;
        }
    }

    private static class DoubleListDescriptor
            extends ListDescriptor {

        private final String leftListType;

        private final String rightListType;

        private Type type;

        public static enum Type {
            SEPARATED,
            ALTERNATED
        };

        public DoubleListDescriptor(
                Type type,
                String listName,
                String leftlistType,
                String rightlistType) {

            super(listName);
            this.type = type;
            this.leftListType = leftlistType;
            this.rightListType = rightlistType;
        }

        public String getLeftListType() {

            return this.leftListType;
        }

        public String getRightListType() {

            return this.rightListType;
        }

        public Type getType() {

            return this.type;
        }
    }

}
TOP

Related Classes of org.sablecc.sablecc.codegeneration.TransformationGeneration$ListDescriptor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.
ga('send', 'pageview');