Java tutorial
/** * Copyright 2015 Chanh Nguyen * * 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 com.mohawk.webcrawler; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import java.util.Queue; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.commons.io.FileUtils; import com.mohawk.webcrawler.lang.BaseEndScope; import com.mohawk.webcrawler.lang.BaseLiteral; import com.mohawk.webcrawler.lang.BaseToken; import com.mohawk.webcrawler.lang.BaseVariable; import com.mohawk.webcrawler.lang.BaseVerb; import com.mohawk.webcrawler.lang.LangCore; import com.mohawk.webcrawler.lang.LanguageException; import com.mohawk.webcrawler.lang.verb.ElseIf_Verb; import com.mohawk.webcrawler.lang.verb.Else_Verb; import com.mohawk.webcrawler.lang.verb.If_Verb; import com.mohawk.webcrawler.lang.verb.While_Verb; public class ScriptCompiler { /** * Takes a script file and creates a queue of string token and verb objects * * @param filename the full file name of the script * @return * @throws IOException * @throws Exception */ public ScriptExecutable compile(File file) throws IOException, CompilationException { List<String> lines = FileUtils.readLines(file, "UTF-8"); StringBuffer fileContents = new StringBuffer(); CommentRemover comment = new CommentRemover(); for (String line : lines) fileContents.append(comment.remove(line)).append(' '); System.out.printf("fileContents %s", fileContents); // reorganize the tokens into scopes return compile0(fileContents.toString()); } public ScriptExecutable compile(String contents) throws CompilationException { return compile0(contents); } /** * Parses out each token in the program, and then calls addScope. * * @param programText * @return * @throws CompilationException */ private static ScriptExecutable compile0(String programText) throws CompilationException { Pattern p = Pattern.compile("\"[^\"]+\"|\\([^\\)]+\\)|[^ \r\n]+"); Matcher m = p.matcher(programText); ArrayList<String> tokensList = new ArrayList<>(); while (m.find()) tokensList.add(m.group(0).trim()); Queue<String> tokensQueue = new LinkedList<>(); for (String token : tokensList) { if (token.trim().length() > 0) tokensQueue.add(token); } // root scope, wil contain both String and BaseVerb objects LinkedList<BaseToken> rootScope = new LinkedList<>(); addScope(tokensQueue, rootScope); return new ScriptExecutable(rootScope); } /** * * @param tokens * @param parentScope */ private static void addScope(Queue<String> tokens, Queue<? super BaseToken> parentScope) throws CompilationException { while (!tokens.isEmpty()) { String token = tokens.poll(); if ("end".equals(token) || "else".equals(token) || "elseif".equals(token)) { parentScope.add(new BaseEndScope(token)); break; } else if ("if".equals(token)) { String expression = tokens.poll(); If_Verb ifVerb = new If_Verb(); ifVerb.setExpression(expression); parentScope.add(ifVerb); addScope(tokens, ifVerb.createScope()); // check if elseif or else is defined LinkedList<BaseToken> ifScope = ifVerb.getScope(); Object elseToken = ifScope.peekLast(); if (elseToken instanceof BaseEndScope) { // remove elseif or else from if scope ifScope.pollLast(); while (elseToken instanceof BaseEndScope) { String elseStr = ((BaseEndScope) elseToken).getName(); if ("end".equals(elseStr)) break; else if ("elseif".equals(elseStr)) { String exp = tokens.poll(); ElseIf_Verb elseIfVerb = new ElseIf_Verb(); elseIfVerb.setExpression(exp); ifVerb.addElseIf(elseIfVerb); addScope(tokens, elseIfVerb.createScope()); elseToken = elseIfVerb.getScope().pollLast(); } else if ("else".equals(elseStr)) { Else_Verb elseVerb = new Else_Verb(); ifVerb.setElse(elseVerb); addScope(tokens, elseVerb.createScope()); elseToken = elseVerb.getScope().pollLast(); } } } } else if ("while".equals(token)) { String evaluation = tokens.poll(); While_Verb whileVerb = new While_Verb(); whileVerb.setExpression(evaluation); parentScope.add(whileVerb); addScope(tokens, whileVerb.createScope()); } else if (LangCore.isVerb(token)) { // verb try { parentScope.add(LangCore.createVerbToken((String) token)); } catch (Exception e) { e.printStackTrace(); throw new CompilationException(e.getLocalizedMessage()); } } else if (LangCore.isLiteral(token)) { // literal try { parentScope.add(new BaseLiteral(LangCore.createLiteralObject(token))); } catch (LanguageException e) { throw new CompilationException(e.getLocalizedMessage()); } } else if (LangCore.isOperator(token)) { // operator try { parentScope.add(LangCore.createOperatorToken(token)); } catch (LanguageException e) { throw new CompilationException(e.getLocalizedMessage()); } } else // default to variable parentScope.add(new BaseVariable(token)); } } }