private void insertComment(ParserRuleReturnScope rule, Boolean newlineBefore, Boolean newlineAfter) { insertComment(rule, newlineBefore, newlineAfter, 1); }
private void insertComment(ParserRuleReturnScope rule) { insertComment(rule, false, false, 0); }
public static int getLastTreePosition(ParserRuleReturnScope tree) { if (tree.Tree==null) { if (tree.Stop!=null && tree.Stop is CommonToken) { return ((CommonToken)tree.Stop).StopIndex+1; //this is necessary for implicit semicolon cases. You will get an extra CR here } return -1; } return getLastTreePosition((CommonTree)tree.Tree); }
/// <summary> /// Insert a comment in the passed String builder /// </summary> /// <param name="tree"></param> private void insertComment(ParserRuleReturnScope rule, Boolean newlineBefore, Boolean newlineAfter, int carriageReturns) { CommonTree tree; CommonTree comment; if(rule != null) { tree = (CommonTree)rule.Tree; // COMMENT_LIST for(int i = 0; i < tree.ChildCount; i++) { if(newlineBefore && i == 0) { for(int n = 0; n < carriageReturns; n++) { buffer.Append(NewLine + tab); } } comment = (CommonTree)tree.GetChild(i); // COMMENT_ENTRY if(comment.GetChild(0).Type == ASLexer.MULTILINE_COMMENT) { string[] lines = lineSplitterReg.Split(comment.GetChild(0).GetChild(0).Text); int k = 0; foreach (string line in lines) { buffer.Append((k > 0 ? " " : "") + line.Trim() + (k < lines.Length-1 ? NewLine + tab : "")); k++; } } else { buffer.Append(comment.GetChild(0).GetChild(0).Text.TrimEnd()); } if(i < tree.ChildCount - 1 || newlineAfter) buffer.Append(NewLine + tab); } } }
public static List<IToken> getHiddenTokens(ParserRuleReturnScope tree, CommonTokenStream rawTokens, bool crossLineBoundaries) { return getHiddenTokens(getFirstTreeToken((CommonTree)tree.Tree), rawTokens, crossLineBoundaries, false); }
public static int getFirstTreePosition(ParserRuleReturnScope tree) { return getFirstTreePosition((CommonTree)tree.Tree); }
public static String getTreeText(ParserRuleReturnScope tree) { return getCommonTreeText((CommonTree)tree.Tree); }
public static List<IToken> getPostHiddenTokens(ParserRuleReturnScope tree, CommonTokenStream rawTokens) { if (tree.Tree==null) { //I think this only happens with implied semicolons if (tree.Start is CommonToken && tree.Start!=null) { //I think we should always be on at least token 1. IToken currentTok=rawTokens.Get(((CommonToken)tree.Start).TokenIndex); //I go back one token if I am on a non-default channel token so that I can search forward for hidden tokens. if (currentTok.Channel!=Token.DEFAULT_CHANNEL) currentTok=rawTokens.Get(((CommonToken)tree.Start).TokenIndex-1); return getPostHiddenTokens(currentTok, rawTokens); } return null; } return getPostHiddenTokens(getLastTreeToken((CommonTree)tree.Tree), rawTokens); }
public bool FindVirtualHiddenToken(ParserRuleReturnScope retval) { int index = ((CommonToken) retval.Start).TokenIndex; if(index<0){ index = input.Count; } for (int ix = index - 1; ix >= 0; ix--){ CommonToken lt = (CommonToken) input.Get(ix); int type = lt.Type; if(lt.Channel == Token.DEFAULT_CHANNEL) break; if (type == EOL || type==COMMENT_SINGLELINE || (type == COMMENT_MULTILINE && Regex.Match(lt.Text,"/.*\r\n|\r|\n").Success)) { retval.Start=lt; return true; } } return false; }
/// <summary> /// This method handles promotion of an EOL token to on channel in situations where the ECMA 3 specification /// states there should be a semicolon inserted because of an EOL between the current (offending) token /// and the previous token. /// So an semicolon is not actually inserted but the EOL present is switched from off to on channel. In this /// way that EOL gets the notion of an "virtual" semicolon. /// As a side effect a given rule's return scope starting point is set to the found EOL and the input stream is repositioned on it. /// A multi line comment with an EOL is also promoted. /// </summary> /// <param name="rule">The invoking rule's return scope</param> public void PromoteEOL(ParserRuleReturnScope<IToken> rule) { // Get current token and its type (the possibly offending token). IToken lt = input.LT(1); int la = lt.Type; // We only need to promote an EOL when the current token is offending (not a SEMIC, EOF, RBRACE or EOL). // Promoting an EOL means switching it from off channel to on channel. if (!(la == SEMIC || la == EOF || la == RBRACE || la == EOL)) { // Start on the possition before the current token and scan backwards off channel tokens until the previous on channel token. for (int ix = lt.TokenIndex - 1; ix > 0; ix--) { lt = input.Get(ix); if (lt.Channel == DefaultTokenChannel) { // On channel token found: stop scanning. break; } else if (lt.Type == EOL || (lt.Type == MultiLineComment && Regex.IsMatch(lt.Text, "/.*\r\n|\r|\n"))) { // We found our EOL: promote it to on channel, position the input on it and reset the rule start. lt.Channel = DefaultTokenChannel; input.Seek(lt.TokenIndex); if (rule != null) { rule.Start = lt; } break; } } } }
private void PromoteEOL(ParserRuleReturnScope rule) { // Get current token and its type (the possibly offending token). IToken lt = input.LT(1); int la = lt.Type; // We only need to promote an EOL when the current token is offending (not a SEMIC, EOF, RBRACE, EOL or MultiLineComment). // EOL and MultiLineComment are not offending as they're already promoted in a previous call to this method. // Promoting an EOL means switching it from off channel to on channel. // A MultiLineComment gets promoted when it contains an EOL. if (!(la == SEMIC || la == EOF || la == RBRACE || la == EOL || la == MultiLineComment)) { // Start on the possition before the current token and scan backwards off channel tokens until the previous on channel token. for (int ix = lt.TokenIndex - 1; ix > 0; ix--) { lt = input.Get(ix); if (lt.Channel == Token.DEFAULT_CHANNEL) { // On channel token found: stop scanning. break; } else if (lt.Type == EOL || (lt.Type == MultiLineComment && (lt.Text.EndsWith("\r") || lt.Text.EndsWith("\n")))) { // We found our EOL: promote the token to on channel, position the input on it and reset the rule start. lt.Channel = Token.DEFAULT_CHANNEL; input.Seek(lt.TokenIndex); if (rule != null) { rule.Start = lt; } break; } } } }
public bool findVirtualHiddenToken(ParserRuleReturnScope retval) { //the point of this method is to look for something that can serve as a semicolon. So a carriage return //or a comment containing a carriage return will fit the bill. int index = ((IToken)retval.Start).TokenIndex; if(index<0){ index = input.Count; } else { IToken lt=input.Get(index); if (lt.Type==EOF || lt.Type==SEMI || lt.Type==RCURLY) return false; } /* //we are on the next regular channel token after the rule. So we walk backward to determine if between //the rule and this token is a single line comment, multiline comment, or new line that can serve as the //end token. If so, then we 'promote' that token by returning it as the 'end' token of the rule (in place //of the semi colon). for (int ix = index - 1; ix >= 0; ix--){ IToken lt = input.Get(ix); int type = lt.Type; if(lt.Channel == Token.DEFAULT_CHANNEL) break; if (type == EOL || type==COMMENT_SINGLELINE || (type == COMMENT_MULTILINE && Regex.Matches(lt.Text, "/.*\r\n|\r|\n").Count > 0)) { retval.Start=lt; return true; } }*/ //the token index is pointing to the next default channel token, which is not what we want. //We want to walk backward to the previous default channel token (first loop), and then walk forward //again looking for EOL/comments (2nd loop) int ix=index-1; for (; ix >= 0; ix--){ IToken lt = input.Get(ix); if(lt.Channel == Token.DEFAULT_CHANNEL) break; } //walk forward again ix++; //to move to next token that's not default channel for (;ix<input.Count;ix++) //now search for the next "statement ender" { IToken lt = input.Get(ix); int type = lt.Type; if (lt.Channel == Token.DEFAULT_CHANNEL) break; if (type == EOL || type==COMMENT_SINGLELINE || (type == COMMENT_MULTILINE && Regex.Matches(lt.Text, "/.*\r\n|\r|\n").Count > 0)) { retval.Start=lt; return true; } } return false; }
public static void IsVarAValidOneForExpression(ParserRuleReturnScope<IToken> expression, CommonTree tree, Dictionary<string, CommonTree> DeclarationDatabase) { bool invalid = false; if (tree != null) { if (tree.Text == "VAR_NODE") { if (DeclarationDatabase.ContainsKey(tree.GetChild(0).Text)) { IsVarAValidOneForExpression(expression, DeclarationDatabase[tree.GetChild(0).Text], DeclarationDatabase); } else { invalid = true; } } else if (tree.Text == "BLOCK_NODE") { foreach (CommonTree statement in tree.Children) { IsVarAValidOneForExpression(expression, statement, DeclarationDatabase); } } else if (tree.Text == "CALL_NODE") { string key = tree.GetChild(1).Text + (tree.ChildCount - 2); if (DeclarationDatabase.ContainsKey(key)) { IsVarAValidOneForExpression(expression, DeclarationDatabase[key], DeclarationDatabase); } } else if (tree.Text == "if") { IsVarAValidOneForExpression(expression, tree.GetChild(1) as CommonTree, DeclarationDatabase); IsVarAValidOneForExpression(expression, tree.GetChild(2) as CommonTree, DeclarationDatabase); } else if (tree.Text == "while") { IsVarAValidOneForExpression(expression, tree.GetChild(1) as CommonTree, DeclarationDatabase); } else if (!ExpressionList.Contains(tree.Text)) { invalid = true; } else if (tree.Text == "CLASS_CALL_NODE" && tree.ChildCount == 2) { if (tree.GetChild(1).Text == "FIELDS_CALL_NODE") { invalid = true; } } } if (invalid) { if (tree.Token.TokenIndex == -1) { throw new ParsingException("Only assignment, call, if, while, local variable declaration, new object creation and object method call can be used as a statement", expression.Start as IToken); } else { throw new ParsingException("Only assignment, call, if, while, local variable declaration, new object creation and object method call can be used as a statement", tree.Token); } } return; }
public static void IsStateAValidOneForExpression(ParserRuleReturnScope<IToken> expression, CommonTree tree) { bool invalid = false; if (tree != null) { if (!ExpressionList.Contains(tree.Text)) { invalid = true; } else if (tree.Text == "CLASS_CALL_NODE" && tree.ChildCount == 2) { if (tree.GetChild(1).Text == "FIELDS_CALL_NODE") { invalid = true; } } } if (invalid) { if (tree.Token.TokenIndex == -1) { throw new ParsingException("Only assignment, call, if, while, local variable declaration, new object creation and object method call can be used as a statement", expression.Start as IToken); } else { throw new ParsingException("Only assignment, call, if, while, local variable declaration, new object creation and object method call can be used as a statement", tree.Token); } } return; }
public static void IsStateAValidOneForBlock(ParserRuleReturnScope<IToken> statement, CommonTree tree) { if (tree != null && !SymbolList.Contains(tree.Text)) { if (tree.Token.TokenIndex == -1) { throw new ParsingException(Resources.Only_a_sequential_program_or_C__method_calls_can_be_associated_with_an_event_, statement.Start as IToken); } else { throw new ParsingException(Resources.Only_a_sequential_program_or_C__method_calls_can_be_associated_with_an_event_, tree.Token); } } return; }