Package com.nexirius.framework.datamodel.parser

Source Code of com.nexirius.framework.datamodel.parser.DataModelParser$CantPushbackException

//{HEADER
/**
* This class is part of jnex 'Nexirius Application Framework for Java'
* Copyright (C) Nexirius GmbH, CH-4450 Sissach, Switzerland (www.nexirius.ch)
*
* <p>This library is free software; you can redistribute it and/or<br>
* modify it under the terms of the GNU Lesser General Public<br>
* License as published by the Free Software Foundation; either<br>
* version 2.1 of the License, or (at your option) any later version.</p>
*
* <p>This library is distributed in the hope that it will be useful,<br>
* but WITHOUT ANY WARRANTY; without even the implied warranty of<br>
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU<br>
* Lesser General Public License for more details.</p>
*
* <p>You should have received a copy of the GNU Lesser General Public<br>
* License along with this library; if not, write to the Free Software<br>
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA</p>
* </blockquote>
*
* <p>
* Nexirius GmbH, hereby disclaims all copyright interest in<br>
* the library jnex' 'Nexirius Application Framework for Java' written<br>
* by Marcel Baumann.</p>
*/
//}HEADER
package com.nexirius.framework.datamodel.parser;

import com.nexirius.framework.datamodel.DataModel;
import com.nexirius.framework.dataviewer.DataViewer;
import com.nexirius.framework.dataviewer.ViewerFactory;
import com.nexirius.util.TextToken;
import com.nexirius.util.resource.ClientResource;
import com.nexirius.util.resource.ClientResourceImpl;

import javax.swing.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;


/*
  Type: (Class | Enum)*

  Class: ClassHeader ClassBody

  ClassHeader: class Identifier StringLiteral

  ClassBody: { ClassElement* }

  ClassElement: Method | SimpleMember | ArrayMember

  Method: Identifier Identifier();

  SimpleMember: Identifier Identifier ;
  | Identifier Identifier = StringLiteral ;

  ArrayMember: Identifier Identifier [];

  Enum: { StringLiteral* }
*/


/**
* A class which parses the DataModel syntax definition
*
* @author Marcel Baumann
*/
public class DataModelParser {



    public static final char OCURLY = '{';
    public static final char CCURLY = '}';
    public static final char OBRACE = '(';
    public static final char CBRACE = ')';
    public static final char OBRACKET = '[';
    public static final char CBRACKET = ']';
    public static final char SEMICOLON = ';';
    public static final char ASSIGN = '=';
    public static final String CLASS = "class";
    public static final String STRING = "String";
    public static final String INTEGER = "Integer";
    public static final String FLOAT = "Float";
    public static final String DATE = "Date";
    public static final String TIME = "Time";
    public static final String TIMESTAMP = "TimeStamp";
    public static final String BOOLEAN = "Boolean";
    public static final String ENUM = "enum";
    public static final String VOID = "void";

    public final String basicType[] =
            {
                STRING, INTEGER, FLOAT, DATE, TIME, TIMESTAMP, BOOLEAN, ENUM, VOID
            };

    public final int basicTypeCode[] =
            {
                1, 2, 5, 6, 8, 7, 3, 4, 1000
            };

    TextToken tokens[] = null;
    int currentToken = -1;
    int numTokens;
    DataModelClasses types;
    DataModelTypeClass currentClass;

    public DataModelParser() {
    }

    public void doPrint(String s) {
        //System.out.println(s);
    }

    public DataModelClasses parse(String src)
            throws Exception {
        tokens = TextToken.getTokensFrom(src);
        numTokens = tokens.length;

        if (numTokens == 0) {
            throw new Exception("No tokens or parser error while parsing '" + src + "'");
        }

        types = new DataModelClasses();

        while (parseType()) {
        }

        return types;
    }

    boolean parseType()
            throws Exception {
        try {
            // check whether the next token is a 'class' or 'enum'
            TextToken t = nextToken();

            if (t.isIdentifier(CLASS)) {
                pushbackToken();

                return parseClass();
            }

            if (t.isIdentifier(ENUM)) {
                pushbackToken();

                return parseEnum();
            }

            throw new SyntaxException("class or enum", t.debugString());
        } catch (NoMoreTokensException ex) {
            return false;
        }
    }

    boolean parseEnum()
            throws Exception {
        try {
            // check whether the next token is a 'enum'
            TextToken t = nextToken();

            if (!t.isIdentifier(ENUM)) {
                throw new SyntaxException(ENUM, t.debugString());
            }

            t = nextToken();

            if (!t.isIdentifier()) {
                throw new SyntaxException("enum name", t.debugString());
            }
//System.out.println("parsing enum " + t.getString());
            DataModelTypeEnum e = new DataModelTypeEnum(t.getString());


            t = nextToken();

            if (!t.isChar(OCURLY)) {
                throw new SyntaxException(OCURLY, t.debugString());
            }

            t = nextToken();

            while (true) {
                if (t.isChar(CCURLY)) {
                    break;
                }

                if (!t.isString()) {
                    throw new SyntaxException("enum value (string literal)", t.debugString());
                }

                e.addValue(t.getString());

                t = nextToken();
            }

            types.add(e);

            return true;
        } catch (NoMoreTokensException ex) {
            throw new Exception("No more tokens while parsing enum");
        }
    }

    boolean parseClass()
            throws Exception {
        if (parseClassHeader()) {
            parseClassBody();

            types.add(currentClass);
            currentClass = null;

            return true;
        }

        return false;
    }

    boolean parseClassHeader()
            throws Exception {
        try {
            // check whether the next token is a 'class'
            TextToken t = nextToken();

            if (!t.isIdentifier(CLASS)) {
                throw new SyntaxException(CLASS, t.debugString());
            }

            t = nextToken();

            if (!t.isIdentifier()) {
                throw new SyntaxException("class name", t.debugString());
            }
//System.out.println("parsing class " + t.getString());
            currentClass = new DataModelTypeClass(t.getString());

            t = nextToken();

            if (t.isString()) {
                currentClass.setImplementedBy(t.getString());
            } else {
                pushbackToken();
            }

        } catch (NoMoreTokensException ex) {
//ex.printStackTrace();
            return false;
        }

        return true;
    }

    boolean parseClassBody()
            throws Exception {
        try {
            TextToken t = nextToken();

            if (!t.isChar(OCURLY)) {
                throw new SyntaxException(OCURLY, t.debugString());
            }

            while (true) {
                t = nextToken();

                if (t.isChar(CCURLY)) {
                    break;
                }

                pushbackToken();

                parseClassElement();
            }
        } catch (NoMoreTokensException ex) {
            return false;
        }

        return true;
    }

    void parseClassElement()
            throws Exception {
        // check whether the next token is a Identifier
        TextToken t = nextToken();

        if (!t.isIdentifier()) {
            throw new SyntaxException("type specifier", t.debugString());
        }

        String type = t.getString();

        t = nextToken();

        if (t.isIdentifier()) {
            // simple member of array member or method
            String memberName = t.getString();

            t = nextToken();

            if (t.isChar(OBRACKET)) {
                t = nextToken();

                if (!t.isChar(CBRACKET)) {
                    throw new SyntaxException(CBRACKET, t.debugString());
                }

                currentClass.append(new DataModelTypeArray(type, memberName));

            } else if (t.isChar(OBRACE)) {
                t = nextToken();

                if (!t.isChar(CBRACE)) {
                    throw new SyntaxException(CBRACE, t.debugString());
                }

                currentClass.append(new DataModelTypeMethod(type, memberName));

            } else if (t.isChar(SEMICOLON)) {
                currentClass.append(new DataModelTypeMember(type, memberName, null));
                pushbackToken();
            } else if (t.isChar(ASSIGN)) {
                t = nextToken();

                if (!t.isString()) {
                    throw new SyntaxException("string literal (init value)", t.debugString());
                }

                currentClass.append(new DataModelTypeMember(type, memberName, t.getString()));
            } else {
                throw new SyntaxException("( or [ or ; or =", t.debugString());
            }

            t = nextToken();

            if (!t.isChar(SEMICOLON)) {
                throw new SyntaxException(SEMICOLON, t.debugString());
            }
        } else {
            throw new SyntaxException("member name", t.debugString());
        }
    }

    TextToken nextToken()
            throws Exception {
        ++currentToken;

        if (currentToken < numTokens) {
            return tokens[currentToken];
        }

        throw new NoMoreTokensException();
    }

    void pushbackToken()
            throws Exception {
        if (currentToken < 0) {

            throw new CantPushbackException();
        }

        --currentToken;
    }

    class SyntaxException extends Exception {
        SyntaxException(String expect, String have) {
            super("Expecting " + expect + " have: " + have);
        }

        SyntaxException(char expect, String have) {
            super("Expecting Character '" + expect + "' have: " + have);
        }
    }

    class NoMoreTokensException extends Exception {
        NoMoreTokensException() {
            super("No more tokens");
        }
    }

    class CantPushbackException extends Exception {
        CantPushbackException() {
            super("Can't pushback token");
        }
    }

    public static void main(String argv[]) {
        String src = ""
                + "enum X {\"a\" \"b\"}                                   "
                + "class Inner {                                   "
                + "  String string = \"hello\";            "
                + "  Integer int = \"2000\";            "
                + "}                                           "
                + "class TestModel \"com.nexirius.framework.datamodel.parser.TestModel\" {                                   "
                + "  Inner inner;            "
                + "  String name = \"Marcel Baumann\";            "
                + "  X enum = \"b\";                "
                + "  X func();                "
                + "  Inner arr[];                "
                + "  Rechnungen rechnungen;                "
                + "}                                           "
                + "class Rechnung {                                   "
                + "  String firma;            "
                + "  String nummer;            "
                + "  String titel;                "
                + "  Date datum;                "
                + "  Integer betrag;                "
                + "  Date zdatum;                "
                + "  Integer zbetrag;                "
                + "}                                           "
                + "class Rechnungen {                                   "
                + "  Rechnung rechnung[];            "
                + "}                                           "
                ;

        try {
            DataModelParser p = new DataModelParser();

            DataModelClasses classes = p.parse(src);

            DataModel model = classes.newInstance("TestModel", null);

            System.out.println(model.dragData());

            JFrame frame = new JFrame();

            frame.addWindowListener(new MyWindowListener());
            ClientResource res = new ClientResourceImpl("TestClient");
            ViewerFactory factory = new ViewerFactory(res);

            factory.setCommandProcessor(new com.nexirius.framework.command.DefaultProcessor());
            DataViewer v = factory.createDefaultEditor(model);

            frame.getContentPane().add(v.getJComponent());

            frame.pack();
            frame.setVisible(true);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}

class MyWindowListener extends WindowAdapter {
    public void windowClosing(WindowEvent e) {
        try {
            System.exit(0);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}








TOP

Related Classes of com.nexirius.framework.datamodel.parser.DataModelParser$CantPushbackException

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.