001: /*
002: [The "BSD licence"]
003: Copyright (c) 2005-2006 Terence Parr
004: All rights reserved.
005:
006: Redistribution and use in source and binary forms, with or without
007: modification, are permitted provided that the following conditions
008: are met:
009: 1. Redistributions of source code must retain the above copyright
010: notice, this list of conditions and the following disclaimer.
011: 2. Redistributions in binary form must reproduce the above copyright
012: notice, this list of conditions and the following disclaimer in the
013: documentation and/or other materials provided with the distribution.
014: 3. The name of the author may not be used to endorse or promote products
015: derived from this software without specific prior written permission.
016:
017: THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
018: IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
019: OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
020: IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
021: INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
022: NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
023: DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
024: THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
025: (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
026: THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
027: */
028: package org.antlr.codegen;
029:
030: import org.antlr.stringtemplate.StringTemplate;
031: import org.antlr.stringtemplate.StringTemplateGroup;
032: import org.antlr.tool.Grammar;
033: import org.antlr.Tool;
034:
035: import java.io.IOException;
036:
037: public class CPPTarget extends Target {
038:
039: public String escapeChar(int c) {
040: // System.out.println("CPPTarget.escapeChar("+c+")");
041: switch (c) {
042: case '\n':
043: return "\\n";
044: case '\t':
045: return "\\t";
046: case '\r':
047: return "\\r";
048: case '\\':
049: return "\\\\";
050: case '\'':
051: return "\\'";
052: case '"':
053: return "\\\"";
054: default:
055: if (c < ' ' || c > 126) {
056: if (c > 255) {
057: String s = Integer.toString(c, 16);
058: // put leading zeroes in front of the thing..
059: while (s.length() < 4)
060: s = '0' + s;
061: return "\\u" + s;
062: } else {
063: return "\\" + Integer.toString(c, 8);
064: }
065: } else {
066: return String.valueOf((char) c);
067: }
068: }
069: }
070:
071: /** Converts a String into a representation that can be use as a literal
072: * when surrounded by double-quotes.
073: *
074: * Used for escaping semantic predicate strings for exceptions.
075: *
076: * @param s The String to be changed into a literal
077: */
078: public String escapeString(String s) {
079: StringBuffer retval = new StringBuffer();
080: for (int i = 0; i < s.length(); i++) {
081: retval.append(escapeChar(s.charAt(i)));
082: }
083:
084: return retval.toString();
085: }
086:
087: protected void genRecognizerHeaderFile(Tool tool,
088: CodeGenerator generator, Grammar grammar,
089: StringTemplate headerFileST, String extName)
090: throws IOException {
091: StringTemplateGroup templates = generator.getTemplates();
092: generator.write(headerFileST, grammar.name + extName);
093: }
094:
095: /** Convert from an ANTLR char literal found in a grammar file to
096: * an equivalent char literal in the target language. For Java, this
097: * is the identify translation; i.e., '\n' -> '\n'. Most languages
098: * will be able to use this 1-to-1 mapping. Expect single quotes
099: * around the incoming literal.
100: * Depending on the charvocabulary the charliteral should be prefixed with a 'L'
101: */
102: public String getTargetCharLiteralFromANTLRCharLiteral(
103: CodeGenerator codegen, String literal) {
104: int c = Grammar.getCharValueFromGrammarCharLiteral(literal);
105: String prefix = "'";
106: if (codegen.grammar.getMaxCharValue() > 255)
107: prefix = "L'";
108: else if ((c & 0x80) != 0) // if in char mode prevent sign extensions
109: return "" + c;
110: return prefix + escapeChar(c) + "'";
111: }
112:
113: /** Convert from an ANTLR string literal found in a grammar file to
114: * an equivalent string literal in the target language. For Java, this
115: * is the identify translation; i.e., "\"\n" -> "\"\n". Most languages
116: * will be able to use this 1-to-1 mapping. Expect double quotes
117: * around the incoming literal.
118: * Depending on the charvocabulary the string should be prefixed with a 'L'
119: */
120: public String getTargetStringLiteralFromANTLRStringLiteral(
121: CodeGenerator codegen, String literal) {
122: StringBuffer buf = Grammar
123: .getUnescapedStringFromGrammarStringLiteral(literal);
124: String prefix = "\"";
125: if (codegen.grammar.getMaxCharValue() > 255)
126: prefix = "L\"";
127: return prefix + escapeString(buf.toString()) + "\"";
128: }
129:
130: /** Character constants get truncated to this value.
131: * TODO: This should be derived from the charVocabulary. Depending on it
132: * being 255 or 0xFFFF the templates should generate normal character
133: * constants or multibyte ones.
134: */
135: public int getMaxCharValue(CodeGenerator codegen) {
136: int maxval = 255; // codegen.grammar.get????();
137: if (maxval <= 255)
138: return 255;
139: else
140: return maxval;
141: }
142: }
|