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 useBaseTemplatesForSynPredFragments()72 public boolean useBaseTemplatesForSynPredFragments() { 73 return false; 74 } 75 76 @Override encodeIntAsCharEscape(int v)77 public String encodeIntAsCharEscape(int v) { 78 return "\\x" + Integer.toHexString(v).toUpperCase(); 79 } 80 81 @Override getTarget64BitStringFromValue(long word)82 public String getTarget64BitStringFromValue(long word) { 83 return "0x" + Long.toHexString(word).toUpperCase(); 84 } 85 86 @Override genRecognizerFile(Tool tool, CodeGenerator generator, Grammar grammar, ST outputFileST)87 protected void genRecognizerFile(Tool tool, CodeGenerator generator, Grammar grammar, ST outputFileST) throws IOException 88 { 89 if (!grammar.getGrammarIsRoot()) 90 { 91 Grammar rootGrammar = grammar.composite.getRootGrammar(); 92 String actionScope = grammar.getDefaultActionScope(grammar.type); 93 Map<String, Object> actions = rootGrammar.getActions().get(actionScope); 94 Object rootNamespace = actions != null ? actions.get("namespace") : null; 95 if (actions != null && rootNamespace != null) 96 { 97 actions = grammar.getActions().get(actionScope); 98 if (actions == null) 99 { 100 actions = new HashMap<String, Object>(); 101 grammar.getActions().put(actionScope, actions); 102 } 103 104 actions.put("namespace", rootNamespace); 105 } 106 } 107 108 generator.getTemplates().registerRenderer(String.class, new StringRenderer(generator, this)); 109 super.genRecognizerFile(tool, generator, grammar, outputFileST); 110 } 111 112 public static class StringRenderer implements AttributeRenderer 113 { 114 private final CodeGenerator _generator; 115 private final CSharp3Target _target; 116 StringRenderer(CodeGenerator generator, CSharp3Target target)117 public StringRenderer(CodeGenerator generator, CSharp3Target target) 118 { 119 _generator = generator; 120 _target = target; 121 } 122 123 @Override toString(Object obj, String formatName, Locale locale)124 public String toString(Object obj, String formatName, Locale locale) 125 { 126 String value = (String)obj; 127 if (value == null || formatName == null) 128 return value; 129 130 if (formatName.equals("id")) { 131 if (_languageKeywords.contains(value)) 132 return "@" + value; 133 134 return value; 135 } else if (formatName.equals("cap")) { 136 return Character.toUpperCase(value.charAt(0)) + value.substring(1); 137 } else if (formatName.equals("string")) { 138 return _target.getTargetStringLiteralFromString(value, true); 139 } else { 140 throw new IllegalArgumentException("Unsupported format name: '" + formatName + "'"); 141 } 142 } 143 } 144 } 145 146