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.analysis.Label; 31import org.antlr.tool.AttributeScope; 32import org.antlr.tool.Grammar; 33import org.antlr.tool.RuleLabelScope; 34 35public class Perl5Target extends Target { 36 public Perl5Target() { 37 targetCharValueEscape['$'] = "\\$"; 38 targetCharValueEscape['@'] = "\\@"; 39 targetCharValueEscape['%'] = "\\%"; 40 AttributeScope.tokenScope.addAttribute("self", null); 41 RuleLabelScope.predefinedLexerRulePropertiesScope.addAttribute("self", null); 42 } 43 44 public String getTargetCharLiteralFromANTLRCharLiteral(final CodeGenerator generator, 45 final String literal) { 46 final StringBuffer buf = new StringBuffer(10); 47 48 final int c = Grammar.getCharValueFromGrammarCharLiteral(literal); 49 if (c < Label.MIN_CHAR_VALUE) { 50 buf.append("\\x{0000}"); 51 } else if (c < targetCharValueEscape.length && 52 targetCharValueEscape[c] != null) { 53 buf.append(targetCharValueEscape[c]); 54 } else if (Character.UnicodeBlock.of((char) c) == 55 Character.UnicodeBlock.BASIC_LATIN && 56 !Character.isISOControl((char) c)) { 57 // normal char 58 buf.append((char) c); 59 } else { 60 // must be something unprintable...use \\uXXXX 61 // turn on the bit above max "\\uFFFF" value so that we pad with zeros 62 // then only take last 4 digits 63 String hex = Integer.toHexString(c | 0x10000).toUpperCase().substring(1, 5); 64 buf.append("\\x{"); 65 buf.append(hex); 66 buf.append("}"); 67 } 68 69 if (buf.indexOf("\\") == -1) { 70 // no need for interpolation, use single quotes 71 buf.insert(0, '\''); 72 buf.append('\''); 73 } else { 74 // need string interpolation 75 buf.insert(0, '\"'); 76 buf.append('\"'); 77 } 78 79 return buf.toString(); 80 } 81 82 public String encodeIntAsCharEscape(final int v) { 83 final int intValue; 84 if ((v & 0x8000) == 0) { 85 intValue = v; 86 } else { 87 intValue = -(0x10000 - v); 88 } 89 90 return String.valueOf(intValue); 91 } 92} 93