Home | History | Annotate | Download | only in codegen
      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  */
     28 package org.antlr.codegen;
     29 
     30 import org.antlr.Tool;
     31 import org.stringtemplate.v4.ST;
     32 import org.stringtemplate.v4.STGroup;
     33 import org.antlr.tool.Grammar;
     34 
     35 import java.io.IOException;
     36 
     37 public 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