1 /* 2 * [The "BSD license"] 3 * Copyright (c) 2005-2008 Terence Parr 4 * All rights reserved. 5 * 6 * Conversion to C#: 7 * Copyright (c) 2008-2010 Sam Harwell, Pixel Mine, Inc. 8 * All rights reserved. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. The name of the author may not be used to endorse or promote products 19 * derived from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 package org.antlr.codegen; 34 35 import org.antlr.Tool; 36 import org.antlr.tool.Grammar; 37 import org.stringtemplate.v4.AttributeRenderer; 38 import org.stringtemplate.v4.ST; 39 40 import java.io.IOException; 41 import java.util.HashMap; 42 import java.util.HashSet; 43 import java.util.Locale; 44 import java.util.Map; 45 46 public class CSharp3Target extends Target { 47 private static final HashSet<String> _languageKeywords = new HashSet<String>() 48 {{ 49 add("abstract"); add("event"); add("new"); add("struct"); 50 add("as"); add("explicit"); add("null"); add("switch"); 51 add("base"); add("extern"); add("object"); add("this"); 52 add("bool"); add("false"); add("operator"); add("throw"); 53 add("break"); add("finally"); add("out"); add("true"); 54 add("byte"); add("fixed"); add("override"); add("try"); 55 add("case"); add("float"); add("params"); add("typeof"); 56 add("catch"); add("for"); add("private"); add("uint"); 57 add("char"); add("foreach"); add("protected"); add("ulong"); 58 add("checked"); add("goto"); add("public"); add("unchecked"); 59 add("class"); add("if"); add("readonly"); add("unsafe"); 60 add("const"); add("implicit"); add("ref"); add("ushort"); 61 add("continue"); add("in"); add("return"); add("using"); 62 add("decimal"); add("int"); add("sbyte"); add("virtual"); 63 add("default"); add("interface"); add("sealed"); add("volatile"); 64 add("delegate"); add("internal"); add("short"); add("void"); 65 add("do"); add("is"); add("sizeof"); add("while"); 66 add("double"); add("lock"); add("stackalloc"); 67 add("else"); add("long"); add("static"); 68 add("enum"); add("namespace"); add("string"); 69 }}; 70 71 @Override 72 public String encodeIntAsCharEscape(int v) { 73 return "\\x" + Integer.toHexString(v).toUpperCase(); 74 } 75 76 @Override 77 public String getTarget64BitStringFromValue(long word) { 78 return "0x" + Long.toHexString(word).toUpperCase(); 79 } 80 81 @Override 82 protected void genRecognizerFile(Tool tool, CodeGenerator generator, Grammar grammar, ST outputFileST) throws IOException 83 { 84 if (!grammar.getGrammarIsRoot()) 85 { 86 Grammar rootGrammar = grammar.composite.getRootGrammar(); 87 String actionScope = grammar.getDefaultActionScope(grammar.type); 88 Map<String, Object> actions = rootGrammar.getActions().get(actionScope); 89 Object rootNamespace = actions != null ? actions.get("namespace") : null; 90 if (actions != null && rootNamespace != null) 91 { 92 actions = grammar.getActions().get(actionScope); 93 if (actions == null) 94 { 95 actions = new HashMap<String, Object>(); 96 grammar.getActions().put(actionScope, actions); 97 } 98 99 actions.put("namespace", rootNamespace); 100 } 101 } 102 103 generator.getTemplates().registerRenderer(String.class, new StringRenderer(generator, this)); 104 super.genRecognizerFile(tool, generator, grammar, outputFileST); 105 } 106 107 public static class StringRenderer implements AttributeRenderer 108 { 109 private final CodeGenerator _generator; 110 private final CSharp3Target _target; 111 112 public StringRenderer(CodeGenerator generator, CSharp3Target target) 113 { 114 _generator = generator; 115 _target = target; 116 } 117 118 public String toString(Object obj, String formatName, Locale locale) 119 { 120 String value = (String)obj; 121 if (value == null || formatName == null) 122 return value; 123 124 if (formatName.equals("id")) { 125 if (_languageKeywords.contains(value)) 126 return "@" + value; 127 128 return value; 129 } else if (formatName.equals("cap")) { 130 return Character.toUpperCase(value.charAt(0)) + value.substring(1); 131 } else if (formatName.equals("string")) { 132 return _target.getTargetStringLiteralFromString(value, true); 133 } else { 134 throw new IllegalArgumentException("Unsupported format name: '" + formatName + "'"); 135 } 136 } 137 } 138 } 139 140