public AttributeDecl(OutputModelFactory factory, Attribute a) : base(factory, a.name, a.decl) { this.Type = a.type; this.InitValue = a.initValue; }
public virtual void AddDecl(Attribute a) { AddDecl(new AttributeDecl(factory, a)); }
/** * For decls like "String foo" or "char *foo32[]" compute the ID * and type declarations. Also handle "int x=3" and 'T t = new T("foo")' * but if the separator is ',' you cannot use ',' in the initvalue * unless you escape use "\," escape. */ public static Attribute ParseAttributeDef([Nullable] ActionAST action, [NotNull] System.Tuple<string, int> decl, Grammar g) { if (decl.Item1 == null) return null; Attribute attr = new Attribute(); int rightEdgeOfDeclarator = decl.Item1.Length - 1; int equalsIndex = decl.Item1.IndexOf('='); if (equalsIndex > 0) { // everything after the '=' is the init value attr.initValue = decl.Item1.Substring(equalsIndex + 1).Trim(); rightEdgeOfDeclarator = equalsIndex - 1; } string declarator = decl.Item1.Substring(0, rightEdgeOfDeclarator + 1); System.Tuple<int, int> p; string text = decl.Item1; text = text.Replace("::", ""); if (text.Contains(":")) { // declarator has type appearing after the name like "x:T" p = _ParsePostfixDecl(attr, declarator, action, g); } else { // declarator has type appearing before the name like "T x" p = _ParsePrefixDecl(attr, declarator, action, g); } int idStart = p.Item1; int idStop = p.Item2; attr.decl = decl.Item1; if (action != null) { string actionText = action.Text; int[] lines = new int[actionText.Length]; int[] charPositionInLines = new int[actionText.Length]; for (int i = 0, line1 = 0, col = 0; i < actionText.Length; i++, col++) { lines[i] = line1; charPositionInLines[i] = col; if (actionText[i] == '\n') { line1++; col = -1; } } int[] charIndexes = new int[actionText.Length]; for (int i = 0, j = 0; i < actionText.Length; i++, j++) { charIndexes[j] = i; // skip comments if (i < actionText.Length - 1 && actionText[i] == '/' && actionText[i + 1] == '/') { while (i < actionText.Length && actionText[i] != '\n') { i++; } } } int declOffset = charIndexes[decl.Item2]; int declLine = lines[declOffset + idStart]; int line = action.Token.Line + declLine; int charPositionInLine = charPositionInLines[declOffset + idStart]; if (declLine == 0) { /* offset for the start position of the ARG_ACTION token, plus 1 * since the ARG_ACTION text had the leading '[' stripped before * reaching the scope parser. */ charPositionInLine += action.Token.CharPositionInLine + 1; } int offset = ((CommonToken)action.Token).StartIndex; attr.token = new CommonToken(action.Token.InputStream, ANTLRParser.ID, BaseRecognizer.DefaultTokenChannel, offset + declOffset + idStart + 1, offset + declOffset + idStop); attr.token.Line = line; attr.token.CharPositionInLine = charPositionInLine; Debug.Assert(attr.name.Equals(attr.token.Text), "Attribute text should match the pseudo-token text at this point."); } return attr; }
public static System.Tuple<int, int> _ParsePostfixDecl(Attribute attr, string decl, ActionAST a, Grammar g) { int start = -1; int stop = -1; int colon = decl.IndexOf(':'); int namePartEnd = colon == -1 ? decl.Length : colon; // look for start of name for (int i = 0; i < namePartEnd; ++i) { char ch = decl[i]; if (char.IsLetterOrDigit(ch) || ch == '_') { start = i; break; } } if (start == -1) { start = 0; g.tool.errMgr.GrammarError(ErrorType.CANNOT_FIND_ATTRIBUTE_NAME_IN_DECL, g.fileName, a.Token, decl); } // look for stop of name for (int i = start; i < namePartEnd; ++i) { char ch = decl[i]; if (!(char.IsLetterOrDigit(ch) || ch == '_')) { stop = i; break; } if (i == namePartEnd - 1) { stop = namePartEnd; } } if (stop == -1) { stop = start; } // extract name from decl attr.name = decl.Substring(start, stop - start); // extract type from decl (could be empty) if (colon == -1) { attr.type = ""; } else { attr.type = decl.Substring(colon + 1, decl.Length - colon - 1); } attr.type = attr.type.Trim(); if (attr.type.Length == 0) { attr.type = null; } return Tuple.Create(start, stop); }
public static System.Tuple<int, int> _ParsePrefixDecl(Attribute attr, string decl, ActionAST a, Grammar g) { // walk backwards looking for start of an ID bool inID = false; int start = -1; for (int i = decl.Length - 1; i >= 0; i--) { char ch = decl[i]; // if we haven't found the end yet, keep going if (!inID && char.IsLetterOrDigit(ch)) { inID = true; } else if (inID && !(char.IsLetterOrDigit(ch) || ch == '_')) { start = i + 1; break; } } if (start < 0 && inID) { start = 0; } if (start < 0) { g.tool.errMgr.GrammarError(ErrorType.CANNOT_FIND_ATTRIBUTE_NAME_IN_DECL, g.fileName, a.Token, decl); } // walk forward looking for end of an ID int stop = -1; for (int i = start; i < decl.Length; i++) { char ch = decl[i]; // if we haven't found the end yet, keep going if (!(char.IsLetterOrDigit(ch) || ch == '_')) { stop = i; break; } if (i == decl.Length - 1) { stop = i + 1; } } // the name is the last ID attr.name = decl.Substring(start, stop - start); // the type is the decl minus the ID (could be empty) attr.type = decl.Substring(0, start); if (stop <= decl.Length - 1) { attr.type += decl.Substring(stop, decl.Length - stop); } attr.type = attr.type.Trim(); if (attr.type.Length == 0) { attr.type = null; } return Tuple.Create(start, stop); }
public virtual Attribute Add(Attribute a) { a.dict = this; return attributes[a.name] = a; }