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