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

org.vesalainen.nmea.script.ScriptParser Maven / Gradle / Ivy

There is a newer version: 1.8.0
Show newest version
/*
 * Copyright (C) 2015 tkv
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see .
 */
package org.vesalainen.nmea.script;

import java.io.IOException;
import java.util.List;
import org.vesalainen.parser.GenClassFactory;
import org.vesalainen.parser.ParserConstants;
import static org.vesalainen.parser.ParserFeature.SingleThread;
import static org.vesalainen.parser.ParserFeature.SyntaxOnly;
import org.vesalainen.parser.annotation.GenClassname;
import org.vesalainen.parser.annotation.GrammarDef;
import org.vesalainen.parser.annotation.ParseMethod;
import org.vesalainen.parser.annotation.ParserContext;
import org.vesalainen.parser.annotation.ReservedWords;
import org.vesalainen.parser.annotation.Rule;
import org.vesalainen.parser.annotation.Rules;
import org.vesalainen.parser.annotation.Terminal;
import org.vesalainen.parser.util.InputReader;
import org.vesalainen.regex.Regex;

/**
 *
 * @author tkv
 * @param 
 */
@GenClassname("org.vesalainen.nmea.script.ScriptParserImpl")
@GrammarDef
public abstract class ScriptParser
{
    @ReservedWords({"if", "else"})
    protected void reservedWords()
    {
        
    }
    @Rule(left = "statements", value = "statement*")
    protected List> statements(List> list)
    {
        return list;
    }
    @Rules({
        @Rule("ifst"),
        @Rule("whilest"),
        @Rule("block"),
        @Rule("send"),
        @Rule("sleep"),
        @Rule("kill"),
        @Rule("restart"),
        @Rule("waitfor"),
        @Rule("loop")
    })
    protected ScriptStatement statement(ScriptStatement ss)
    {
        return ss;
    }
    @Rule("'if' '\\(' statement '\\)' block ( 'else' block )?")
    protected ScriptStatement ifst(
            ScriptStatement expr, 
            ScriptStatement successStat, 
            ScriptStatement elseStat, 
            @ParserContext("factory") ScriptObjectFactory factory
    ) throws IOException, InterruptedException
    {
        ScriptStatement ifst = factory.createIf(ensureType(Boolean.class, expr), successStat, elseStat);
        return ifst;
    }
    @Rule("'while' '\\(' statement '\\)' block ")
    protected ScriptStatement whilest(
            ScriptStatement expr, 
            ScriptStatement stat, 
            @ParserContext("factory") ScriptObjectFactory factory
    ) throws IOException, InterruptedException
    {
        ScriptStatement whilest = factory.createWhile(ensureType(Boolean.class, expr), stat);
        return whilest;
    }
    @Rule("'\\{' statements '\\}'")
    protected ScriptStatement block(List> sList, @ParserContext("factory") ScriptObjectFactory factory) throws IOException, InterruptedException
    {
        ScriptStatement block = factory.createBlock(sList);
        return block;
    }
    @Rule("'loop' '\\(' integer '\\)' block")
    protected ScriptStatement loop(Number times, ScriptStatement stat, @ParserContext("factory") ScriptObjectFactory factory) throws IOException, InterruptedException
    {
        ScriptStatement looper = factory.createLooper(times.intValue(), stat);
        return looper;
    }
    @Rule("'kill' '\\(' identifier '\\)'")
    protected ScriptStatement kill(String target, @ParserContext("factory") ScriptObjectFactory factory) throws IOException, InterruptedException
    {
        ScriptStatement killer = factory.createKiller(target);
        return killer;
    }
    @Rule("'restart' '\\(' '\\)'")
    protected ScriptStatement restart(@ParserContext("factory") ScriptObjectFactory factory) throws IOException, InterruptedException
    {
        ScriptStatement restarter = factory.createRestarter();
        return restarter;
    }
    @Rule("'sleep' '\\(' integer '\\)'")
    protected ScriptStatement sleep(Number millis, @ParserContext("factory") ScriptObjectFactory factory) throws IOException, InterruptedException
    {
        ScriptStatement sleeper = factory.createSleeper(millis.longValue());
        return sleeper;
    }
    @Rule("'waitfor' '\\(' integer '\\,' string '\\)'")
    protected ScriptStatement waitfor(Number millis, String msg, @ParserContext("factory") ScriptObjectFactory factory) throws IOException, InterruptedException
    {
        ScriptStatement waiter = factory.createWaiter(millis.longValue(), msg);
        return waiter;
    }
    @Rule("'send' '\\(' string '\\)'")
    protected ScriptStatement send(String msg, @ParserContext("factory") ScriptObjectFactory factory) throws IOException, InterruptedException
    {
        ScriptStatement sender = factory.createSender(msg);
        return sender;
    }
    @Rule("'send' '\\(' identifier '\\,' string '\\)'")
    protected ScriptStatement send(String to, String msg, @ParserContext("factory") ScriptObjectFactory factory) throws IOException, InterruptedException
    {
        ScriptStatement sender = factory.createSender(to, msg);
        return sender;
    }
    public static  ScriptParser newInstance()
    {
        return (ScriptParser) GenClassFactory.loadGenInstance(ScriptParser.class);
    }
    @ParseMethod(
            start = "statements", 
            features = {SingleThread},
            whiteSpace = {"whiteSpace", "hashComment", "cComment"}
    )
    public abstract List exec(String script, @ParserContext("factory") ScriptObjectFactory factory);
    
    @ParseMethod(
            start = "statements", 
            features = {SyntaxOnly, SingleThread},
            whiteSpace = {"whiteSpace", "hashComment", "cComment"}
    )
    public abstract List check(String script);
    
    @Terminal(expression = "[a-zA-z][a-zA-z0-9_]*")
    protected abstract String identifier(String value);

    @Terminal(expression = "'[^']*'|\"[^\"]*\"|`[^´]´")
    protected String string(String value)
    {
        return value.substring(1, value.length() - 1);
    }

    @Terminal(expression = "[\\+\\-]?[0-9]+")
    protected Number integer(String value)
    {
        return Long.parseLong(value);
    }

    @Terminal(expression = "[\\+\\-]?[0-9]+\\.[0-9]+")
    protected Number decimal(String value)
    {
        return Double.parseDouble(value);
    }

    @Terminal(expression = "[ \t\r\n]+")
    protected abstract void whiteSpace();

    @Terminal(expression = "#[^\n]*\n")
    protected void hashComment(
            @ParserContext(ParserConstants.INPUTREADER) InputReader reader
            )
    {
    }

    @Terminal(expression = "/\\*.*\\*/", options =
    {
        Regex.Option.FIXED_ENDER
    })
    protected void cComment(
            @ParserContext(ParserConstants.INPUTREADER) InputReader reader
            )
    {
    }
    private  ScriptStatement ensureType(Class expected, Object checked)
    {
        try
        {
            return (ScriptStatement) checked;
        }
        catch (ClassCastException ex)
        {
            throw new IllegalArgumentException(checked+" is not ScriptStatement<"+expected+">");
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy