1/* 2 * [The "BSD license"] 3 * Copyright (c) 2010 Terence Parr 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28package org.antlr.codegen; 29 30import org.antlr.Tool; 31import org.stringtemplate.v4.ST; 32import org.stringtemplate.v4.STGroup; 33import org.antlr.tool.Grammar; 34 35import java.io.IOException; 36 37public class CPPTarget extends Target { 38 39 public String escapeChar( int c ) { 40 // System.out.println("CPPTarget.escapeChar("+c+")"); 41 switch (c) { 42 case '\n' : return "\\n"; 43 case '\t' : return "\\t"; 44 case '\r' : return "\\r"; 45 case '\\' : return "\\\\"; 46 case '\'' : return "\\'"; 47 case '"' : return "\\\""; 48 default : 49 if ( c < ' ' || c > 126 ) 50 { 51 if (c > 255) 52 { 53 String s = Integer.toString(c,16); 54 // put leading zeroes in front of the thing.. 55 while( s.length() < 4 ) 56 s = '0' + s; 57 return "\\u" + s; 58 } 59 else { 60 return "\\" + Integer.toString(c,8); 61 } 62 } 63 else { 64 return String.valueOf((char)c); 65 } 66 } 67 } 68 69 /** Converts a String into a representation that can be use as a literal 70 * when surrounded by double-quotes. 71 * 72 * Used for escaping semantic predicate strings for exceptions. 73 * 74 * @param s The String to be changed into a literal 75 */ 76 public String escapeString(String s) 77 { 78 StringBuffer retval = new StringBuffer(); 79 for (int i = 0; i < s.length(); i++) { 80 retval.append(escapeChar(s.charAt(i))); 81 } 82 83 return retval.toString(); 84 } 85 86 protected void genRecognizerHeaderFile(Tool tool, 87 CodeGenerator generator, 88 Grammar grammar, 89 ST headerFileST, 90 String extName) 91 throws IOException 92 { 93 generator.write(headerFileST, grammar.name+extName); 94 } 95 96 /** Convert from an ANTLR char literal found in a grammar file to 97 * an equivalent char literal in the target language. For Java, this 98 * is the identify translation; i.e., '\n' -> '\n'. Most languages 99 * will be able to use this 1-to-1 mapping. Expect single quotes 100 * around the incoming literal. 101 * Depending on the charvocabulary the charliteral should be prefixed with a 'L' 102 */ 103 public String getTargetCharLiteralFromANTLRCharLiteral( 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( CodeGenerator codegen, String literal) { 121 StringBuffer buf = Grammar.getUnescapedStringFromGrammarStringLiteral(literal); 122 String prefix = "\""; 123 if( codegen.grammar.getMaxCharValue() > 255 ) 124 prefix = "L\""; 125 return prefix+escapeString(buf.toString())+"\""; 126 } 127 /** Character constants get truncated to this value. 128 * TODO: This should be derived from the charVocabulary. Depending on it 129 * being 255 or 0xFFFF the templates should generate normal character 130 * constants or multibyte ones. 131 */ 132 public int getMaxCharValue( CodeGenerator codegen ) { 133 int maxval = 255; // codegen.grammar.get????(); 134 if ( maxval <= 255 ) 135 return 255; 136 else 137 return maxval; 138 } 139} 140