1 28 package org.jruby.lexer.yacc; 29 30 import org.jruby.ast.StrNode; 31 import org.jruby.parser.Tokens; 32 import org.jruby.util.ByteList; 33 34 35 public class HeredocTerm extends StrTerm { 36 private final String eos; 37 private final int func; 38 private final String lastLine; 39 40 public HeredocTerm(String eos, int func, String lastLine) { 41 this.eos = eos; 42 this.func = func; 43 this.lastLine = lastLine; 44 } 45 46 public int parseString(RubyYaccLexer lexer, LexerSource src) throws java.io.IOException { 47 char c; 48 boolean indent = (func & RubyYaccLexer.STR_FUNC_INDENT) != 0; 49 ByteList str = new ByteList(); 50 51 if ((c = src.read()) == RubyYaccLexer.EOF) { 52 throw new SyntaxException(src.getPosition(), "can't find string \"" + eos + "\" anywhere before EOF"); 53 } 54 if (src.wasBeginOfLine() && src.matchString(eos + '\n', indent)) { 55 src.unreadMany(lastLine); 56 return Tokens.tSTRING_END; 57 } 58 59 if ((func & RubyYaccLexer.STR_FUNC_EXPAND) == 0) { 60 63 64 73 74 78 src.unread(c); 79 do { 80 str.append(src.readLineBytes()); 81 str.append('\n'); 82 83 if (src.peek('\0')) { 84 throw new SyntaxException(src.getPosition(), "can't find string \"" + eos + "\" anywhere before EOF"); 85 } 86 } while (!src.matchString(eos + '\n', indent)); 87 } else { 88 ByteList buffer = new ByteList(); 89 if (c == '#') { 90 switch (c = src.read()) { 91 case '$': 92 case '@': 93 src.unread(c); 94 lexer.setValue(new Token("#" + c, lexer.getPosition())); 95 return Tokens.tSTRING_DVAR; 96 case '{': 97 lexer.setValue(new Token("#" + c, lexer.getPosition())); 98 return Tokens.tSTRING_DBEG; 99 } 100 buffer.append('#'); 101 } 102 103 src.unread(c); 104 105 do { 106 if ((c = new StringTerm(func, '\n', '\0').parseStringIntoBuffer(src, buffer)) == RubyYaccLexer.EOF) { 107 throw new SyntaxException(src.getPosition(), "can't find string \"" + eos + "\" anywhere before EOF"); 108 } 109 if (c != '\n') { 110 lexer.yaccValue = new StrNode(lexer.getPosition(), buffer); 111 return Tokens.tSTRING_CONTENT; 112 } 113 buffer.append(src.read()); 114 if ((c = src.read()) == RubyYaccLexer.EOF) { 115 throw new SyntaxException(src.getPosition(), "can't find string \"" + eos + "\" anywhere before EOF"); 116 } 117 src.unread(c); 120 } while (!src.matchString(eos + '\n', indent)); 121 str = buffer; 122 } 123 124 src.unreadMany(lastLine); 125 lexer.setStrTerm(new StringTerm(-1, '\0', '\0')); 126 lexer.yaccValue = new StrNode(lexer.getPosition(), str); 127 return Tokens.tSTRING_CONTENT; 128 } 129 } 130 | Popular Tags |