Home | History | Annotate | Download | only in codegen
      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 boolean useBaseTemplatesForSynPredFragments() {
     73         return false;
     74     }
     75 
     76     @Override
     77     public String encodeIntAsCharEscape(int v) {
     78         return "\\x" + Integer.toHexString(v).toUpperCase();
     79     }
     80 
     81     @Override
     82     public String getTarget64BitStringFromValue(long word) {
     83         return "0x" + Long.toHexString(word).toUpperCase();
     84     }
     85 
     86     @Override
     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 
    117         public StringRenderer(CodeGenerator generator, CSharp3Target target)
    118         {
    119             _generator = generator;
    120             _target = target;
    121         }
    122 
    123 		@Override
    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