Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial commit for parser tokens to store col, line info
Browse files Browse the repository at this point in the history
adambeynon committed Nov 21, 2013

Verified

This commit was signed with the committer’s verified signature.
lukekarrys Luke Karrys
1 parent 8ebbaa2 commit a65bfca
Showing 6 changed files with 2,130 additions and 2,103 deletions.
4 changes: 4 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -15,3 +15,7 @@ notifications:
matrix:
allow_failures:
- rvm: rbx-20mode

branches:
except:
- parser_tokens
134 changes: 99 additions & 35 deletions lib/opal/parser.rb
Original file line number Diff line number Diff line change
@@ -28,9 +28,9 @@ def next_token
@lexer.next_token
end

def s(*parts)
sexp = Sexp.new(parts)
sexp.line = @lexer.line
def s(type, children = [], source = [])
sexp = Sexp.new([type].concat(children))
sexp.loc = source
sexp
end

@@ -51,8 +51,76 @@ def on_error(t, val, vstack)
raise "parse error on value #{val.inspect} (#{token_to_str(t) || '?'}) :#{@file}:#{lexer.line}"
end

def value(tok)
tok[0]
end

def source(tok)
tok[1]
end

def new_nil(tok)
s(:nil, [], source(tok))
end

def new_self(tok)
s(:self, [], source(tok))
end

def new_true(tok)
s(:true, [], source(tok))
end

def new_false(tok)
s(:false, [], source(tok))
end

def new___FILE__(tok)
s(:str, [self.file], source(tok))
end

def new___LINE__(tok)
s(:int, [lexer.line], source(tok))
end

def new_ident(tok)
s(:identifier, [value(tok).to_sym], source(tok))
end

def new_int(tok)
s(:int, [value(tok)], source(tok))
end

def new_float(tok)
s(:float, [value(tok)], source(tok))
end

def new_ivar(tok)
s(:ivar, [value(tok).to_sym], source(tok))
end

def new_gvar(tok)
s(:gvar, [value(tok).to_sym], source(tok))
end

def new_cvar(tok)
s(:cvar, [value(tok).to_sym], source(tok))
end

def new_const(tok)
s(:const, [value(tok).to_sym], source(tok))
end

def new_sym(tok)
s(:sym, [value(tok).to_sym], source(tok))
end

def new_alias(kw, new, old)
s(:alias, [new, old], source(kw))
end

def new_block(stmt = nil)
s = s(:block)
s = s(:block, [], nil)
s << stmt if stmt
s
end
@@ -63,9 +131,9 @@ def new_compstmt(block)
elsif block.size == 2
block[1]
else
block.line = block[1].line
block
end
block
end

def new_body(compstmt, res, els, ens)
@@ -91,8 +159,8 @@ def new_def(line, recv, name, args, body)
s
end

def new_class(path, sup, body)
s(:class, path, sup, body)
def new_class(start, path, sup, body, endt)
s(:class, [path, sup, body], source(start))
end

def new_sclass(expr, body)
@@ -110,11 +178,25 @@ def new_iter(args, body)
s
end

def new_if(expr, stmt, tail)
s = s(:if, expr, stmt, tail)
s.line = expr.line
s.end_line = @lexer.line
s
def new_if(if_tok, expr, stmt, tail)
s(:if, [expr, stmt, tail], source(if_tok))
end

def new_while(kw, test, body)
s(:while, [test, body], source(kw))
end

def new_until(kw, test, body)
s(:until, [test, body], source(kw))
end

def new_rescue_mod(kw, expr, resc)
s(:rescue_mod, [expr, resc], source(kw))
end

def new_array(start, args, finish)
args ||= []
s(:array, args, source(start))
end

def new_args(norm, opt, rest, block)
@@ -192,26 +274,8 @@ def new_block_args(norm, opt, rest, block)
end
end

def new_call(recv, meth, args = nil)
call = s(:call, recv, meth)
args = s(:arglist) unless args
args.type = :arglist if args.type == :array
call << args

if recv
call.line = recv.line
elsif args[1]
call.line = args[1].line
end

# fix arglist spilling over into next line if no args
if args.length == 1
args.line = call.line
else
args.line = args[1].line
end

call
def new_call(recv, meth, args = [])
s(:call, [recv, value(meth).to_sym, s(:arglist, args)], source(meth))
end

def add_block_pass(arglist, block)
@@ -237,7 +301,7 @@ def new_op_asgn(op, lhs, rhs)
result
end

def new_assign(lhs, rhs)
def new_assign(lhs, tok, rhs)
case lhs.type
when :iasgn, :cdecl, :lasgn, :gasgn, :cvdecl, :nth_ref
lhs << rhs
@@ -312,9 +376,9 @@ def new_var_ref(ref)
ref
when :identifier
if scope.has_local? ref[1]
s(:lvar, ref[1])
s(:lvar, [ref[1]])
else
s(:call, nil, ref[1], s(:arglist))
s(:call, [nil, ref[1], s(:arglist)])
end
else
raise "Bad var_ref type: #{ref.type}"
3,988 changes: 1,982 additions & 2,006 deletions lib/opal/parser/grammar.rb

Large diffs are not rendered by default.

101 changes: 40 additions & 61 deletions lib/opal/parser/grammar.y
Original file line number Diff line number Diff line change
@@ -45,19 +45,10 @@ preclow
rule

program: top_compstmt
{
result = val[0]
}

top_compstmt: top_stmts opt_terms
{
comp = new_compstmt val[0]
if comp and comp.type == :begin and comp.size == 2
result = comp[1]
result.line = comp.line
else
result = comp
end
result = new_compstmt val[0]
}

top_stmts: # none
@@ -87,13 +78,7 @@ rule

compstmt: stmts opt_terms
{
comp = new_compstmt val[0]
if comp and comp.type == :begin and comp.size == 2
result = comp[1]
result.line = comp.line
else
result = comp
end
result = new_compstmt val[0]
}

stmts: # none
@@ -116,7 +101,7 @@ rule
}
fitem
{
result = s(:alias, val[1], val[3])
result = new_alias(val[0], val[1], val[3])
}
| kALIAS tGVAR tGVAR
{
@@ -133,28 +118,28 @@ rule
}
| stmt kIF_MOD expr_value
{
result = new_if val[2], val[0], nil
result = new_if(val[1], val[2], val[0], nil)
}
| stmt kUNLESS_MOD expr_value
{
result = new_if val[2], nil, val[0]
result = new_if(val[1], val[2], nil, val[0])
}
| stmt kWHILE_MOD expr_value
{
result = s(:while, val[2], val[0], true)
result = new_while(val[1], val[2], val[0])
}
| stmt kUNTIL_MOD expr_value
{
result = s(:until, val[2], val[0], true)
result = new_until(val[1], val[2], val[0])
}
| stmt kRESCUE_MOD stmt
{
result = s(:rescue_mod, val[0], val[2])
result = new_rescue_mod(val[1], val[0], val[2])
}
| klEND tLCURLY compstmt tRCURLY
| lhs tEQL command_call
{
result = new_assign val[0], val[2]
result = new_assign(val[0], val[1], val[2])
}
| mlhs tEQL command_call
{
@@ -239,7 +224,7 @@ rule

command: operation command_args =tLOWEST
{
result = new_call nil, val[0].intern, val[1]
result = new_call(nil, val[0], val[1])
}
| operation command_args cmd_brace_block
| primary_value tDOT operation2 command_args =tLOWEST
@@ -388,7 +373,7 @@ rule
}
| cname
{
result = val[0].intern
result = new_const(val[0])
}
| primary_value tCOLON2 cname
{
@@ -441,7 +426,7 @@ rule

arg: lhs tEQL arg
{
result = new_assign val[0], val[2]
result = new_assign(val[0], val[1], val[2])
}
| lhs tEQL arg kRESCUE_MOD arg
{
@@ -634,7 +619,7 @@ rule

paren_args: tLPAREN2 none tRPAREN
{
result = nil
result = []
}
| tLPAREN2 call_args opt_nl tRPAREN
{
@@ -709,19 +694,19 @@ rule

args: arg_value
{
result = s(:array, val[0])
result = [val[0]]
}
| tSTAR arg_value
{
result = s(:array, s(:splat, val[1]))
result = [new_splat(val[0], val[1])]
}
| args tCOMMA arg_value
{
result = val[0] << val[2]
}
| args tCOMMA tSTAR arg_value
{
result = val[0] << s(:splat, val[3])
result = val[0] << new_splat(val[2], val[3])
}

mrhs: args tCOMMA arg_value
@@ -775,7 +760,7 @@ rule
}
| tLBRACK aref_args tRBRACK
{
result = val[1] || s(:array)
result = new_array(val[0], val[1], val[2])
}
| '{' assoc_list tRCURLY
{
@@ -885,19 +870,13 @@ rule
# ...
}
compstmt kEND
| kCLASS
{
result = lexer.line
}
cpath superclass
| kCLASS cpath superclass
{
# ...
}
bodystmt kEND
{
result = new_class val[2], val[3], val[5]
result.line = val[1]
result.end_line = lexer.line
result = new_class val[0], val[1], val[2], val[4], val[5]
}
| kCLASS tLSHFT
{
@@ -1123,23 +1102,23 @@ opt_block_args_tail: tCOMMA block_args_tail

method_call: operation paren_args
{
result = new_call nil, val[0].intern, val[1]
result = new_call(nil, val[0], val[1])
}
| primary_value tDOT operation2 opt_paren_args
{
result = new_call val[0], val[2].intern, val[3]
result = new_call(val[0], val[2], val[3])
}
| primary_value tDOT paren_args
{
result = new_call val[0], :call, val[2]
result = new_call(val[0], [:call, []], val[2])
}
| primary_value tCOLON2 operation2 paren_args
{
result = new_call val[0], val[2].intern, val[3]
result = new_call(val[0], val[2], val[3])
}
| primary_value tCOLON2 operation3
{
result = new_call val[0], val[2].intern, s(:arglist)
result = new_call(val[0], val[2])
}
| kSUPER paren_args
{
@@ -1368,12 +1347,12 @@ xstring_contents: none

symbol: tSYMBEG sym
{
result = s(:sym, val[1].intern)
result = new_sym(val[1])
lexer.lex_state = :expr_end
}
| tSYMBOL
{
result = s(:sym, val[0].intern)
result = new_sym(val[0])
}

sym: fname
@@ -1388,63 +1367,63 @@ xstring_contents: none

numeric: tINTEGER
{
result = s(:int, val[0])
result = new_int(val[0])
}
| tFLOAT
{
result = s(:float, val[0])
result = new_float(val[0])
}
| '-@NUM' tINTEGER =tLOWEST
| '-@NUM' tFLOAT =tLOWEST

variable: tIDENTIFIER
{
result = s(:identifier, val[0].intern)
result = new_ident(val[0])
}
| tIVAR
{
result = s(:ivar, val[0].intern)
result = new_ivar(val[0])
}
| tGVAR
{
result = s(:gvar, val[0].intern)
result = new_gvar(val[0])
}
| tCONSTANT
{
result = s(:const, val[0].intern)
result = new_const(val[0])
}
| tCVAR
{
result = s(:cvar, val[0].intern)
result = new_cvar(val[0])
}
| kNIL
{
result = s(:nil)
result = new_nil(val[0])
}
| kSELF
{
result = s(:self)
result = new_self(val[0])
}
| kTRUE
{
result = s(:true)
result = new_true(val[0])
}
| kFALSE
{
result = s(:false)
result = new_false(val[0])
}
| k__FILE__
{
result = s(:str, self.file)
result = new___FILE__(val[0])
}
| k__LINE__
{
result = s(:int, lexer.line)
result = new___LINE__(val[0])
}

var_ref: variable
{
result = new_var_ref val[0]
result = new_var_ref(val[0])
}

var_lhs: variable
4 changes: 3 additions & 1 deletion lib/opal/parser/lexer.rb
Original file line number Diff line number Diff line change
@@ -96,7 +96,9 @@ def matched
end

def next_token
self.yylex
old = self.yylex
loc = []
[old[0], [old[1], loc]]
end

def strterm_expand?(strterm)
2 changes: 2 additions & 0 deletions lib/opal/parser/sexp.rb
Original file line number Diff line number Diff line change
@@ -5,6 +5,8 @@ class Sexp
attr_accessor :end_line
attr_reader :array

attr_accessor :loc

def initialize(args)
@array = args
end

0 comments on commit a65bfca

Please sign in to comment.