Skip to content

Commit

Permalink
Fixes #2154. Parser needs to support "foo": hash key syntax
Browse files Browse the repository at this point in the history
  • Loading branch information
enebo committed Jan 18, 2015
1 parent a1e5645 commit 39c7e33
Show file tree
Hide file tree
Showing 9 changed files with 4,038 additions and 3,909 deletions.
4 changes: 0 additions & 4 deletions core/src/main/java/org/jruby/lexer/yacc/HeredocTerm.java
Expand Up @@ -65,10 +65,6 @@ public HeredocTerm(ByteList marker, int func, ByteList lastLine) {
this.lastLine = lastLine;
}

public int getNest() {
return 0;
}

public int parseString(RubyLexer lexer, LexerSource src) throws java.io.IOException {
boolean indent = (flags & RubyLexer.STR_FUNC_INDENT) != 0;

Expand Down
33 changes: 31 additions & 2 deletions core/src/main/java/org/jruby/lexer/yacc/RubyLexer.java
Expand Up @@ -326,6 +326,7 @@ public void newtok() {

// Count of nested parentheses
private int parenNest = 0;
private int braceNest = 0;

private int leftParenBegin = 0;

Expand All @@ -335,6 +336,14 @@ public int incrementParenNest() {
return parenNest;
}

public int getBraceNest() {
return braceNest;
}

public void setBraceNest(int nest) {
braceNest = nest;
}

public int getLeftParenBegin() {
return leftParenBegin;
}
Expand All @@ -356,6 +365,8 @@ public final void reset() {
resetStacks();
lex_strterm = null;
commandStart = true;
parenNest = 0;
braceNest = 0;
}

public int nextToken() throws IOException {
Expand Down Expand Up @@ -469,6 +480,10 @@ private void printState() {
}
}

public LexState getState() {
return lex_state;
}

public void setState(LexState state) {
this.lex_state = state;
// printState();
Expand Down Expand Up @@ -1094,7 +1109,16 @@ private int yylex() throws IOException {

if (lex_strterm != null) {
int tok = lex_strterm.parseString(this, src);
if (tok == Tokens.tSTRING_END || tok == Tokens.tREGEXP_END) {

if (tok == Tokens.tSTRING_END && (yaccValue.equals("\"") || yaccValue.equals("'"))) {
if (((lex_state == LexState.EXPR_BEG || lex_state == LexState.EXPR_ENDFN) && !conditionState.isInState() ||
isARG()) && src.peek(':')) {
src.read();
tok = Tokens.tLABEL_END;
}
}

if (tok == Tokens.tSTRING_END || tok == Tokens.tREGEXP_END || tok == Tokens.tLABEL_END) {
lex_strterm = null;
setState(LexState.EXPR_END);
}
Expand Down Expand Up @@ -1861,6 +1885,8 @@ private int leftBracket(boolean spaceSeen) throws IOException {
}

private int leftCurly() {
braceNest++;
//System.out.println("lcurly: " + braceNest);
if (leftParenBegin > 0 && leftParenBegin == parenNest) {
setState(LexState.EXPR_BEG);
leftParenBegin = 0;
Expand Down Expand Up @@ -2182,7 +2208,10 @@ private int rightCurly() {
cmdArgumentState.restart();
setState(LexState.EXPR_ENDARG);
yaccValue = "}";
return Tokens.tRCURLY;
//System.out.println("braceNest: " + braceNest);
int tok = /*braceNest != 0 ? Tokens.tSTRING_DEND : */ Tokens.tRCURLY;
braceNest--;
return tok;
}

private int rightParen() {
Expand Down
1 change: 0 additions & 1 deletion core/src/main/java/org/jruby/lexer/yacc/StrTerm.java
Expand Up @@ -28,6 +28,5 @@
package org.jruby.lexer.yacc;

public abstract class StrTerm {
public abstract int getNest();
public abstract int parseString(RubyLexer lexer, LexerSource src) throws java.io.IOException;
}
5 changes: 1 addition & 4 deletions core/src/main/java/org/jruby/lexer/yacc/StringTerm.java
Expand Up @@ -56,10 +56,6 @@ public StringTerm(int flags, int begin, int end) {
this.nest = 0;
}

public int getNest() {
return nest;
}

protected ByteList createByteList(RubyLexer lexer) {
return new ByteList(new byte[]{}, lexer.getEncoding());
}
Expand Down Expand Up @@ -134,6 +130,7 @@ private int parsePeekVariableName(RubyLexer lexer, LexerSource src) throws IOExc
break;
}
case '{':
//lexer.setBraceNest(lexer.getBraceNest() + 1);
lexer.setValue("#" + (char) c);
return Tokens.tSTRING_DBEG;
default:
Expand Down
977 changes: 504 additions & 473 deletions core/src/main/java/org/jruby/parser/RubyParser.java

Large diffs are not rendered by default.

36 changes: 28 additions & 8 deletions core/src/main/java/org/jruby/parser/RubyParser.y
Expand Up @@ -213,7 +213,8 @@ public class RubyParser {
%token <RegexpNode> tREGEXP_END
%type <RestArgNode> f_rest_arg
%type <Node> singleton strings string string1 xstring regexp
%type <Node> string_contents xstring_contents string_content method_call
%type <Node> string_contents xstring_contents method_call
%type <Object> string_content
%type <Node> regexp_contents
%type <Node> words qwords word literal numeric simple_numeric dsym cpath command_asgn command_call
%type <Node> mrhs_arg
Expand Down Expand Up @@ -264,6 +265,7 @@ public class RubyParser {
%token <String> tSTRING_DEND
%type <String> kwrest_mark, f_kwrest, f_label
%type <FCallNode> fcall
%token <String> tLABEL_END, tSTRING_DEND

/*
* precedence table
Expand Down Expand Up @@ -1909,9 +1911,11 @@ word_list : /* none */ {
$$ = $1.add($2 instanceof EvStrNode ? new DStrNode($1.getPosition(), lexer.getEncoding()).add($2) : $2);
}

word : string_content
word : string_content {
$$ = $<Node>1;
}
| word string_content {
$$ = support.literal_concat(support.getPosition($1), $1, $2);
$$ = support.literal_concat(support.getPosition($1), $1, $<Node>2);
}

symbols : tSYMBOLS_BEG ' ' tSTRING_END {
Expand Down Expand Up @@ -1963,22 +1967,22 @@ string_contents : /* none */ {
$$ = lexer.createStrNode(lexer.getPosition(), aChar, 0);
}
| string_contents string_content {
$$ = support.literal_concat($1.getPosition(), $1, $2);
$$ = support.literal_concat($1.getPosition(), $1, $<Node>2);
}

xstring_contents: /* none */ {
$$ = null;
}
| xstring_contents string_content {
$$ = support.literal_concat(support.getPosition($1), $1, $2);
$$ = support.literal_concat(support.getPosition($1), $1, $<Node>2);
}

regexp_contents : /* none */ {
$$ = null;
}
| regexp_contents string_content {
// FIXME: mri is different here.
$$ = support.literal_concat(support.getPosition($1), $1, $2);
$$ = support.literal_concat(support.getPosition($1), $1, $<Node>2);
}

string_content : tSTRING_CONTENT {
Expand All @@ -1994,16 +1998,19 @@ string_content : tSTRING_CONTENT {
}
| tSTRING_DBEG {
$$ = lexer.getStrTerm();
lexer.setStrTerm(null);
lexer.getConditionState().stop();
lexer.getCmdArgumentState().stop();
lexer.setStrTerm(null);
} {
$$ = lexer.getState();
lexer.setState(LexState.EXPR_BEG);
} compstmt tRCURLY {
lexer.getConditionState().restart();
lexer.getCmdArgumentState().restart();
lexer.setStrTerm($<StrTerm>2);
lexer.setState($<LexState>3);

$$ = support.newEvStrNode(support.getPosition($3), $3);
$$ = support.newEvStrNode(support.getPosition($4), $4);
}

string_dvar : tGVAR {
Expand Down Expand Up @@ -2446,6 +2453,19 @@ assoc : arg_value tASSOC arg_value {
SymbolNode label = new SymbolNode(support.getPosition($2), new ByteList($1.getBytes(), lexer.getEncoding()));
$$ = new KeyValuePair<Node,Node>(label, $2);
}
| tSTRING_BEG string_contents tLABEL_END arg_value {
if ($2 instanceof StrNode) {
DStrNode dnode = new DStrNode(support.getPosition($2), lexer.getEncoding());
dnode.add($2);
$$ = new KeyValuePair<Node,Node>(new DSymbolNode(support.getPosition($2), dnode), $4);
} else if ($2 instanceof DStrNode) {
$$ = new KeyValuePair<Node,Node>(new DSymbolNode(support.getPosition($2), $<DStrNode>2), $4);
} else {
support.compile_error("Uknown type for assoc in strings: " + $2);
}

}

| tDSTAR arg_value {
$$ = new KeyValuePair<Node,Node>(null, $2);
}
Expand Down
2 changes: 2 additions & 0 deletions core/src/main/java/org/jruby/parser/Tokens.java
Expand Up @@ -161,6 +161,8 @@ public interface Tokens {
int tSYMBOLS_BEG = RubyParser.tSYMBOLS_BEG;
int tQSYMBOLS_BEG = RubyParser.tQSYMBOLS_BEG;
int tDSTAR = RubyParser.tDSTAR;
int tLABEL_END = RubyParser.tLABEL_END;
int tSTRING_DEND = RubyParser.tSTRING_DEND;

String[] operators = {"+@", "-@", "**", "<=>", "==", "===", "!=", ">=", "<=", "&&",
"||", "=~", "!~", "..", "...", "[]", "[]=", "<<", ">>", "::"};
Expand Down

0 comments on commit 39c7e33

Please sign in to comment.