/* * Copyright (C) 2012 Sony Mobile Communications AB * * This file is part of ApkAnalyser. * * 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 codegen; import java.util.ArrayList; import java.util.List; public class Parser { List<Identifier> m_identifiers = new ArrayList<Identifier>(); public void add(Identifier id) { m_identifiers.add(id); } public void parse(ParserReporter report, StringBuffer sb) { int index = 0; int len = sb.length(); while (index >= 0 && index < len) { //System.out.print(">>> INDEX " + index + "/" + len); index = parseRecurse(report, sb, m_identifiers, index, len); } } protected int parseRecurse(ParserReporter report, StringBuffer sb, List<Identifier> identifiers, int index, int end) { //int len = sb.length(); boolean nomatch = true; for (int i = 0; i < identifiers.size(); i++) { Identifier id = identifiers.get(i); //System.out.println("\t\t\tPROCESSING " + id + " " + index + "-" + end); int curIndex = index; boolean cont = true; while (cont && curIndex < end) { //System.out.print(">>> CURINDEX " + curIndex + "/" + end); String pre = id.getPre(); String post = id.getPost(); if (pre != null) { curIndex = sb.indexOf(pre, curIndex); } if (curIndex == -1 || curIndex >= end) { //System.out.println("\t\t\t\t" + id + "\tfail pre " + index + "-" + end); cont = false; } if (cont) { if (pre != null) { curIndex += pre.length(); } int start = curIndex; if (post != null) { curIndex = sb.indexOf(post, curIndex); } else { curIndex = end - 1; } int stop = curIndex; if (curIndex == -1 || curIndex >= end || start == stop) { //System.out.println("\t\t\t\t" + id + "\tfail post " + index + "-" + end); cont = false; } if (cont) { nomatch = false; if (post != null) { curIndex += post.length(); } //System.out.print("\t\t\t\t" + id + "\t match at " + start + "-" + stop + " " + index + "-" + end); //System.out.println(" [" + sb.substring(start, stop).replace('\n', ' ') + "]"); if (id.hasSubIdentifiers()) { int nextIndex = parseRecurse(report, sb, id.getSubIdentifiers(), start, stop); if (pre == null && post == null) { nomatch = nextIndex == (end - 1); } curIndex = nextIndex; } else { report.match(id, sb, start, stop); } cont &= id.isMultiple(); index = curIndex; } } } if (nomatch) { index = end; } } return index; } public static class Identifier { String m_pre; String m_post; String m_name; boolean m_multiple; List<Identifier> m_subIdentifiers = new ArrayList<Identifier>(); public Identifier(boolean multiple) { this(null, null, multiple, "[SCOPE]"); } public Identifier(boolean multiple, String name) { this(null, null, multiple, name); } public Identifier(String pre, String post, boolean multiple) { this(pre, post, multiple, "[" + pre + " - " + post + "]"); } public Identifier(String pre, String post, boolean multiple, String name) { m_pre = pre; m_post = post; m_multiple = multiple; m_name = name; } public String getPre() { return m_pre; } public String getPost() { return m_post; } public void add(Identifier id) { m_subIdentifiers.add(id); } public List<Identifier> getSubIdentifiers() { return m_subIdentifiers; } public boolean hasSubIdentifiers() { return !m_subIdentifiers.isEmpty(); } public boolean isMultiple() { return m_multiple; } @Override public String toString() { return m_name; } } }