parser working except subprocess mode

This commit is contained in:
adam j hartz 2015-03-24 16:36:27 -04:00
parent 37e61cb96a
commit ed897c813a
4 changed files with 65 additions and 48 deletions

View file

@ -98,7 +98,6 @@ class CtxAwareTransformer(NodeTransformer):
def try_subproc_toks(self, node):
"""Tries to parse the line of the node as a subprocess."""
print('trying to run as subprocess')
line = self.lines[node.lineno - 1]
mincol = len(line) - len(line.lstrip())
maxcol = None# if self.mode == 'eval' else node.col_offset

View file

@ -49,11 +49,20 @@ def handle_indent(state, token, stream):
level = len(token.string)
if token.type == tokenize.DEDENT:
state['indents'].pop()
yield _new_token(state, 'DEDENT', ' '*state['indents'][-1], token.start[0], token.start[1])
yield _new_token(state, 'DEDENT', ' '*state['indents'][-1], token.start)
elif token.type == tokenize.INDENT:
#moving forward
state['indents'].append(level)
yield _new_token(state, 'INDENT', token.string, token.start[0], token.start[1])
yield _new_token(state, 'INDENT', token.string, token.start)
try:
n = next(stream)
except:
n = None
if n is not None:
if n.type != tokenize.ENDMARKER:
for i in handle_token(state, n, stream):
yield i
def handle_dollar(state, token, stream):
try:
@ -65,13 +74,13 @@ def handle_dollar(state, token, stream):
raise Exception("unexpected whitespace after $")
if n.type == tokenize.NAME:
yield _new_token(state, 'DOLLAR_NAME', '$' + n.string, token.start[0], token.start[1])
yield _new_token(state, 'DOLLAR_NAME', '$' + n.string, token.start)
elif n.type == tokenize.OP and n.string == '(':
yield _new_token(state, 'DOLLAR_LPAREN', '$(', token.start[0], token.start[1])
yield _new_token(state, 'DOLLAR_LPAREN', '$(', token.start)
elif n.type == tokenize.OP and n.string == '[':
yield _new_token(state, 'DOLLAR_LBRACKET', '$[', token.start[0], token.start[1])
yield _new_token(state, 'DOLLAR_LBRACKET', '$[', token.start)
elif n.type == tokenize.OP and n.string == '{':
yield _new_token(state, 'DOLLAR_LBRACE', '${', token.start[0], token.start[1])
yield _new_token(state, 'DOLLAR_LBRACE', '${', token.start)
else:
e = 'expected NAME, (, [, or {{ after $, but got {0}'
raise Exception(e.format(n))
@ -84,9 +93,9 @@ def handle_at(state, token, stream):
if n.type == tokenize.OP and n.string == '(' and \
n.start == token.end:
yield _new_token(state, 'AT_LPAREN', '@(', token.start[0], token.start[1])
yield _new_token(state, 'AT_LPAREN', '@(', token.start)
else:
yield _new_token(state, 'AT', '@', token.start[0], token.start[1])
yield _new_token(state, 'AT', '@', token.start)
for i in handle_token(state, n, stream):
yield i
@ -98,9 +107,9 @@ def handle_question(state, token, stream):
if n.type == tokenize.ERRORTOKEN and n.string == '?' and \
n.start == token.end:
yield _new_token(state, 'DOUBLE_QUESTION', '??', token.start[0], token.start[1])
yield _new_token(state, 'DOUBLE_QUESTION', '??', token.start)
else:
yield _new_token(state, 'QUESTION', '?', token.start[0], token.start[1])
yield _new_token(state, 'QUESTION', '?', token.start)
for i in handle_token(state, n, stream):
yield i
@ -123,7 +132,7 @@ def handle_backtick(state, token, stream):
except:
n = None
if found_match:
yield _new_token(state, 'REGEXPATH', sofar, token.start[0], token.start[1])
yield _new_token(state, 'REGEXPATH', sofar, token.start)
else:
e = "Could not find matching backtick for regex on line {0}"
raise Exception(e.format(token.start[0]))
@ -134,7 +143,7 @@ def handle_newline(state, token, stream):
except:
n = None
yield _new_token(state, 'NEWLINE', '\n', token.start[0], token.start[1])
yield _new_token(state, 'NEWLINE', '\n', token.start)
if n is not None:
if n.type != tokenize.ENDMARKER:
@ -156,11 +165,12 @@ special_handlers = {
def handle_token(state, token, stream):
typ = token.type
st = token.string
print('trying', typ, st)
#print('state',state)
#print('handling', typ, st)
if (typ, st) in token_map:
yield _new_token(state, token_map[(typ, st)], st, token.start[0], token.start[1])
yield _new_token(state, token_map[(typ, st)], st, token.start)
elif typ in token_map:
yield _new_token(state, token_map[typ], st, token.start[0], token.start[1])
yield _new_token(state, token_map[typ], st, token.start)
elif (typ, st) in special_handlers:
for i in special_handlers[(typ, st)](state, token, stream):
yield i
@ -171,8 +181,8 @@ def handle_token(state, token, stream):
raise Exception('Unexpected token: {0}'.format(token))
def preprocess_tokens(tokstream):
#tokstream = clear_NL(tokstream)
state = {'indents': [0], 'lexpos': 0}
tokstream = clear_NL(tokstream)
state = {'indents': [0]}
for token in tokstream:
for i in handle_token(state, token, tokstream):
yield i
@ -188,15 +198,11 @@ def tok(s):
#synthesize a new PLY token
def _new_token(state, type, value, lineno, col):
def _new_token(state, type, value, pos):
o = LexToken()
o.type = type
o.value = value
o.lineno = lineno
o.lexpos = state['lexpos']
o.col = col
print('col',col)
state['lexpos'] += 1
o.lineno, o.lexpos = pos
return o
def anyof(*regexes):
@ -237,7 +243,7 @@ class Lexer(object):
self.reset()
def reset(self):
self.lexer.lineno = 1
#self.lexer.lineno = 1
self.indent = ''
self.last = None
self.in_py_mode = [True]
@ -255,15 +261,15 @@ class Lexer(object):
def input(self, s):
"""Calls the lexer on the string s."""
print('code:\n',repr(s))
#print('code:\n',repr(s))
self.token_stream = preprocess_tokens(tok(s))
def token(self):
"""Retrieves the next token."""
try:
o = next(self.token_stream)
print(o)
return o
self.last = next(self.token_stream)
#print(self.last)
return self.last
except:
return None

View file

@ -158,7 +158,7 @@ class Parser(object):
lexer_kwargs = dict(optimize=lexer_optimize, lextab=lexer_table)
if outputdir is not None:
lexer_kwargs['outputdir'] = outputdir
lexer.build(**lexer_kwargs)
#lexer.build(**lexer_kwargs)
self.tokens = lexer.tokens
opt_rules = (
@ -333,15 +333,21 @@ class Parser(object):
def token_col(self, t):
"""Gets ths token column"""
return t.lexpos
return self.lexer.token_col(t)
@property
def lineno(self):
try:
return self.lexer.last.lineno
except:
return 0
return self.lexer.lineno
@lineno.setter
def lineno(self, value):
self.lexer.lineno = value
pass
#self.lexer.lineno = value
@property
def col(self):
@ -1531,6 +1537,8 @@ class Parser(object):
p1 = ast.Str(s=p1.strip(bt), lineno=self.lineno,
col_offset=self.col)
p1 = xonsh_regexpath(p1, lineno=self.lineno, col=self.col)
elif p1.startswith('$'):
p1 = self._envvar_by_name(p1[1:], lineno=self.lineno, col=self.col)
else:
p1 = ast.Name(id=p1, ctx=ast.Load(), lineno=self.lineno,
col_offset=self.col)
@ -1956,8 +1964,18 @@ class Parser(object):
return ast.Subscript(value=xenv, slice=idx, ctx=ast.Load(),
lineno=lineno, col_offset=col)
def _hz_printer(self, x):
if hasattr(x, 'elts'):
return [self._hz_printer(i) for i in x.elts]
elif hasattr(x, 's'):
return x.s
elif hasattr(x, 'n'):
return x.n
def _subproc_cliargs(self, args, lineno=None, col=None):
"""Creates an expression for subprocess CLI arguments."""
print('cliargs enter',lineno,col)
print([self._hz_printer(i) for i in args])
cliargs = currlist = empty_list(lineno=lineno, col=col)
for arg in args:
action = arg._cliarg_action
@ -1982,6 +2000,7 @@ class Parser(object):
else:
raise ValueError("action not understood: " + action)
del arg._cliarg_action
print(self._hz_printer(cliargs))
return cliargs
def p_subproc_special_atom(self, p):
@ -2028,6 +2047,7 @@ class Parser(object):
cliargs = self._subproc_cliargs(p[3], lineno=lineno, col=col)
p0 = p1 + [p[2], cliargs]
# return arguments list
print('subproc_return',p0)
p[0] = p0
def p_subproc_atoms(self, p):
@ -2150,4 +2170,4 @@ class Parser(object):
else:
msg = 'code: {0}'.format(p.value),
self._parse_error(msg, self.currloc(lineno=p.lineno,
column=self.lexer.token_col(p)))
column=p.lexpos))

View file

@ -35,33 +35,27 @@ def subproc_toks(line, mincol=-1, maxcol=None, lexer=None, returnline=False):
subprocess $[] starting at a minimum column. If there are no tokens
(ie in a comment line) this returns None.
"""
line = line if line.endswith('\n') else (line+'\n')
if not line.endswith('\n'):
line = line + '\n'
if lexer is None:
lexer = builtins.__xonsh_execer__.parser.lexer
if maxcol is None:
print(len(line))
maxcol = len(line) + 1
print(maxcol)
print(len(line), repr(line), maxcol)
lexer.reset()
lexer.input(line)
toks = []
end_offset = 0
for tok in lexer:
print('TOKEN',tok)
pos = tok.col
pos = tok.lexpos
if pos >= maxcol:
print(pos,maxcol)
print('too far')
print('too big',pos,maxcol)
break
if len(toks) > 0 and toks[-1].type == 'SEMI':
print('semi')
toks.clear()
if pos < mincol:
print('minicol')
continue
toks.append(tok)
if tok.type in ('NEWLINE', 'ENDMARKER'):
if tok.type =='NEWLINE':
break
else:
if len(toks) == 0:
@ -69,7 +63,7 @@ def subproc_toks(line, mincol=-1, maxcol=None, lexer=None, returnline=False):
if toks[-1].type == 'SEMI':
toks.pop()
tok = toks[-1]
pos = tok.col
pos = tok.lexpos
if isinstance(tok.value, string_types):
end_offset = len(tok.value)
else:
@ -77,10 +71,8 @@ def subproc_toks(line, mincol=-1, maxcol=None, lexer=None, returnline=False):
end_offset = len(el)
if len(toks) == 0:
return # handle comment lines
print(toks)
beg, end = toks[0].col, (toks[-1].col + end_offset)
print('LINE,BEG,END', (line,beg,end))
print('LINE:',line[beg:end])
beg, end = toks[0].lexpos, (toks[-1].lexpos + end_offset)
print(repr(line), toks, beg, end)
rtn = '$[' + line[beg:end] + ']'
if returnline:
rtn = line[:beg] + rtn + line[end:]