1324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/* 2324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * [The "BSD license"] 3324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Copyright (c) 2010 Terence Parr 4324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * All rights reserved. 5324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 6324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Redistribution and use in source and binary forms, with or without 7324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * modification, are permitted provided that the following conditions 8324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * are met: 9324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 1. Redistributions of source code must retain the above copyright 10324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * notice, this list of conditions and the following disclaimer. 11324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 2. Redistributions in binary form must reproduce the above copyright 12324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * notice, this list of conditions and the following disclaimer in the 13324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * documentation and/or other materials provided with the distribution. 14324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 3. The name of the author may not be used to endorse or promote products 15324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * derived from this software without specific prior written permission. 16324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 17324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 28324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 29324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverpackage org.antlr.tool; 30324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 31324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.antlr.codegen.CodeGenerator; 32324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.antlr.runtime.Token; 33324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 34324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport java.util.*; 35324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 36324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/** Track the attributes within a scope. A named scoped has just its list 37324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * of attributes. Each rule has potentially 3 scopes: return values, 38324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * parameters, and an implicitly-named scope (i.e., a scope defined in a rule). 39324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Implicitly-defined scopes are named after the rule; rules and scopes then 40324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * must live in the same name space--no collisions allowed. 41324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 42324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverpublic class AttributeScope { 43324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 44324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** All token scopes (token labels) share the same fixed scope of 45324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * of predefined attributes. I keep this out of the runtime.Token 46324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * object to avoid a runtime space burden. 47324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 48324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public static AttributeScope tokenScope = new AttributeScope("Token",null); 49324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver static { 50324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver tokenScope.addAttribute("text", null); 51324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver tokenScope.addAttribute("type", null); 52324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver tokenScope.addAttribute("line", null); 53324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver tokenScope.addAttribute("index", null); 54324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver tokenScope.addAttribute("pos", null); 55324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver tokenScope.addAttribute("channel", null); 56324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver tokenScope.addAttribute("tree", null); 57324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver tokenScope.addAttribute("int", null); 58324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 59324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 60324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** This scope is associated with which input token (for error handling)? */ 61324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public Token derivedFromToken; 62324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 63324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public Grammar grammar; 64324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 65324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** The scope name */ 66324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver private String name; 67324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 68324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** Not a rule scope, but visible to all rules "scope symbols { ...}" */ 69324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public boolean isDynamicGlobalScope; 70324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 71324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** Visible to all rules, but defined in rule "scope { int i; }" */ 72324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public boolean isDynamicRuleScope; 73324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 74324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public boolean isParameterScope; 75324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 76324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public boolean isReturnScope; 77324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 78324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public boolean isPredefinedRuleScope; 79324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 80324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public boolean isPredefinedLexerRuleScope; 81324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 82324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** The list of Attribute objects */ 83324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver protected LinkedHashMap<String,Attribute> attributes = new LinkedHashMap(); 84324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 85324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* Placeholder for compatibility with the CSharp3 target. */ 86324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public LinkedHashMap<String, GrammarAST> actions = new LinkedHashMap(); 87324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 88324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public AttributeScope(String name, Token derivedFromToken) { 89324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver this(null,name,derivedFromToken); 90324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 91324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 92324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public AttributeScope(Grammar grammar, String name, Token derivedFromToken) { 93324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver this.grammar = grammar; 94324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver this.name = name; 95324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver this.derivedFromToken = derivedFromToken; 96324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 97324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 98324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public String getName() { 99324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( isParameterScope ) { 100324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return name+"_parameter"; 101324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 102324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else if ( isReturnScope ) { 103324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return name+"_return"; 104324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 105324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return name; 106324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 107324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 108324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** From a chunk of text holding the definitions of the attributes, 109324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * pull them apart and create an Attribute for each one. Add to 110324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * the list of attributes for this scope. Pass in the character 111324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * that terminates a definition such as ',' or ';'. For example, 112324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 113324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * scope symbols { 114324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * int n; 115324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * List names; 116324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * } 117324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 118324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * would pass in definitions equal to the text in between {...} and 119324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * separator=';'. It results in two Attribute objects. 120324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 121324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public void addAttributes(String definitions, int separator) { 122324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver List<String> attrs = new ArrayList<String>(); 123324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver CodeGenerator.getListOfArgumentsFromAction(definitions,0,-1,separator,attrs); 124324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (String a : attrs) { 125324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver Attribute attr = new Attribute(a); 126324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( !isReturnScope && attr.initValue!=null ) { 127324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ErrorManager.grammarError(ErrorManager.MSG_ARG_INIT_VALUES_ILLEGAL, 128324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver grammar, 129324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver derivedFromToken, 130324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver attr.name); 131324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver attr.initValue=null; // wipe it out 132324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 133324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver attributes.put(attr.name, attr); 134324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 135324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 136324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 137324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public void addAttribute(String name, String decl) { 138324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver attributes.put(name, new Attribute(name,decl)); 139324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 140324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 141324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** Given @scope::name {action} define it for this attribute scope. Later, 142324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * the code generator will ask for the actions table. 143324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 144324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public final void defineNamedAction(GrammarAST nameAST, GrammarAST actionAST) 145324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 146324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver String actionName = nameAST.getText(); 147324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver GrammarAST a = actions.get(actionName); 148324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (a != null) { 149324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ErrorManager.grammarError(ErrorManager.MSG_ACTION_REDEFINITION, 150324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver grammar, 151324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver nameAST.getToken(), 152324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver nameAST.getText()); 153324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } else { 154324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver actions.put(actionName, actionAST); 155324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 156324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 157324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 158324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public Attribute getAttribute(String name) { 159324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return (Attribute)attributes.get(name); 160324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 161324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 162324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** Used by templates to get all attributes */ 163324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public List<Attribute> getAttributes() { 164324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver List<Attribute> a = new ArrayList<Attribute>(); 165324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver a.addAll(attributes.values()); 166324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return a; 167324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 168324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 169324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** Return the set of keys that collide from 170324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * this and other. 171324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 172324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public Set intersection(AttributeScope other) { 173324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( other==null || other.size()==0 || size()==0 ) { 174324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return null; 175324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 176324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver Set inter = new HashSet(); 177324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver Set thisKeys = attributes.keySet(); 178324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (Iterator it = thisKeys.iterator(); it.hasNext();) { 179324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver String key = (String) it.next(); 180324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( other.attributes.get(key)!=null ) { 181324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver inter.add(key); 182324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 183324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 184324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( inter.size()==0 ) { 185324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return null; 186324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 187324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return inter; 188324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 189324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 190324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public int size() { 191324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return attributes==null?0:attributes.size(); 192324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 193324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 194324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public String toString() { 195324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return (isDynamicGlobalScope?"global ":"")+getName()+":"+attributes; 196324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 197324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 198