| /* |
| * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. Oracle designates this |
| * particular file as subject to the "Classpath" exception as provided |
| * by Oracle in the LICENSE file that accompanied this code. |
| * |
| * This code 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 |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| |
| package build.tools.jdwpgen; |
| |
| import java.util.*; |
| import java.io.*; |
| |
| class Parse { |
| |
| final StreamTokenizer izer; |
| final Map<String, Node> kindMap = new HashMap<String, Node>(); |
| |
| Parse(Reader reader) { |
| izer = new StreamTokenizer(new BufferedReader(reader)); |
| izer.resetSyntax(); |
| izer.slashStarComments(true); |
| izer.slashSlashComments(true); |
| izer.wordChars((int)'a', (int)'z'); |
| izer.wordChars((int)'A', (int)'Z'); |
| izer.wordChars((int)'0', (int)'9'); |
| izer.wordChars((int)'_', (int)'_'); |
| izer.wordChars((int)'-', (int)'-'); |
| izer.wordChars((int)'.', (int)'.'); |
| izer.whitespaceChars(0, 32); |
| izer.quoteChar('"'); |
| izer.quoteChar('\''); |
| |
| kindMap.put("CommandSet", new CommandSetNode()); |
| kindMap.put("Command", new CommandNode()); |
| kindMap.put("Out", new OutNode()); |
| kindMap.put("Reply", new ReplyNode()); |
| kindMap.put("ErrorSet", new ErrorSetNode()); |
| kindMap.put("Error", new ErrorNode()); |
| kindMap.put("Event", new EventNode()); |
| kindMap.put("Repeat", new RepeatNode()); |
| kindMap.put("Group", new GroupNode()); |
| kindMap.put("Select", new SelectNode()); |
| kindMap.put("Alt", new AltNode()); |
| kindMap.put("ConstantSet", new ConstantSetNode()); |
| kindMap.put("Constant", new ConstantNode()); |
| kindMap.put("int", new IntTypeNode()); |
| kindMap.put("long", new LongTypeNode()); |
| kindMap.put("boolean", new BooleanTypeNode()); |
| kindMap.put("object", new ObjectTypeNode()); |
| kindMap.put("threadObject", new ThreadObjectTypeNode()); |
| kindMap.put("threadGroupObject", new ThreadGroupObjectTypeNode()); |
| kindMap.put("arrayObject", new ArrayObjectTypeNode()); |
| kindMap.put("stringObject", new StringObjectTypeNode()); |
| kindMap.put("classLoaderObject", new ClassLoaderObjectTypeNode()); |
| kindMap.put("classObject", new ClassObjectTypeNode()); |
| kindMap.put("referenceType", new ReferenceTypeNode()); |
| kindMap.put("referenceTypeID", new ReferenceIDTypeNode()); |
| kindMap.put("classType", new ClassTypeNode()); |
| kindMap.put("interfaceType", new InterfaceTypeNode()); |
| kindMap.put("arrayType", new ArrayTypeNode()); |
| kindMap.put("method", new MethodTypeNode()); |
| kindMap.put("field", new FieldTypeNode()); |
| kindMap.put("frame", new FrameTypeNode()); |
| kindMap.put("string", new StringTypeNode()); |
| kindMap.put("value", new ValueTypeNode()); |
| kindMap.put("byte", new ByteTypeNode()); |
| kindMap.put("location", new LocationTypeNode()); |
| kindMap.put("tagged-object", new TaggedObjectTypeNode()); |
| kindMap.put("referenceTypeID", new ReferenceIDTypeNode()); |
| kindMap.put("typed-sequence", new ArrayRegionTypeNode()); |
| kindMap.put("untagged-value", new UntaggedValueTypeNode()); |
| } |
| |
| RootNode items() throws IOException { |
| List<Node> list = new ArrayList<Node>(); |
| |
| while (izer.nextToken() != StreamTokenizer.TT_EOF) { |
| izer.pushBack(); |
| list.add(item()); |
| } |
| RootNode node = new RootNode(); |
| node.set("Root", list, 1); |
| return node; |
| } |
| |
| Node item() throws IOException { |
| switch (izer.nextToken()) { |
| case StreamTokenizer.TT_EOF: |
| error("Unexpect end-of-file"); |
| return null; |
| |
| case StreamTokenizer.TT_WORD: { |
| String name = izer.sval; |
| if (izer.nextToken() == '=') { |
| int ntok = izer.nextToken(); |
| if (ntok == StreamTokenizer.TT_WORD) { |
| return new NameValueNode(name, izer.sval); |
| } else if (ntok == '\'') { |
| return new NameValueNode(name, izer.sval.charAt(0)); |
| } else { |
| error("Expected value after: " + name + " ="); |
| return null; |
| } |
| } else { |
| izer.pushBack(); |
| return new NameNode(name); |
| } |
| } |
| |
| case '"': |
| return new CommentNode(izer.sval); |
| |
| case '(': { |
| if (izer.nextToken() == StreamTokenizer.TT_WORD) { |
| String kind = izer.sval; |
| List<Node> list = new ArrayList<Node>(); |
| |
| while (izer.nextToken() != ')') { |
| izer.pushBack(); |
| list.add(item()); |
| } |
| Node proto = kindMap.get(kind); |
| if (proto == null) { |
| error("Invalid kind: " + kind); |
| return null; |
| } else { |
| try { |
| Node node = (Node)proto.getClass().newInstance(); |
| node.set(kind, list, izer.lineno()); |
| return node; |
| } catch (InstantiationException exc) { |
| error(exc.toString()); |
| return null; |
| } catch (IllegalAccessException exc) { |
| error(exc.toString()); |
| return null; |
| } |
| } |
| } else { |
| error("Expected kind identifier, got " + izer.ttype + |
| " : " + izer.sval); |
| return null; |
| } |
| } |
| |
| default: |
| error("Unexpected character: '" + (char)izer.ttype + "'"); |
| return null; |
| } |
| } |
| |
| void error(String errmsg) { |
| System.err.println(Main.specSource + ":" + izer.lineno() + |
| ": " + errmsg); |
| throw new RuntimeException("Error: " + errmsg); |
| } |
| } |