Skip to content

Commit

Permalink
Improve parsing error message a little (this is associated with #29)
Browse files Browse the repository at this point in the history
  • Loading branch information
i2y committed Apr 29, 2015
1 parent 7ec1b67 commit 1df2c01
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 46 deletions.
29 changes: 12 additions & 17 deletions mochi/core/builtins.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#!/usr/bin/env python
import sys
import traceback
from types import FunctionType
from functools import reduce, partial
from itertools import chain
Expand All @@ -10,11 +9,11 @@

from pyrsistent import pmap

from mochi.parser import lex
from .utils import issequence, issequence_except_str, is_tuple_or_list
from .constants import *
from .exceptions import UnquoteSplicingError, DuplicatedDefError, ReadError
from .global_env import global_env
from mochi.parser import lex
from .translation import binding_name_set_stack, translator, Keyword, parse


Expand Down Expand Up @@ -996,21 +995,17 @@ def tuple_it(obj):


def eval_tokens(tokens):
try:
sexps = parse(tokens.__iter__())
for sexp in sexps:
if isinstance(sexp, MutableSequence):
sexp = tuple_it(sexp)
if sexp is COMMENT:
continue
py_ast = translator.translate_sexp_to_interact(sexp)
if py_ast is not None:
code = compile(py_ast, '<string>', 'exec')
if code is not None:
exec(code, global_env)
# print(file=current_output_port)
except Exception:
traceback.print_exc(file=current_error_port)
sexps = parse(tokens.__iter__())
for sexp in sexps:
if isinstance(sexp, MutableSequence):
sexp = tuple_it(sexp)
if sexp is COMMENT:
continue
py_ast = translator.translate_sexp_to_interact(sexp)
if py_ast is not None:
code = compile(py_ast, '<string>', 'exec')
if code is not None:
exec(code, global_env)


@builtin_rename('eval')
Expand Down
2 changes: 1 addition & 1 deletion mochi/core/constants.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import ast

from .global_env import global_env
from mochi.parser.parser import Symbol
from mochi.parser import Symbol


# -----------------------------------------------
Expand Down
36 changes: 23 additions & 13 deletions mochi/core/main.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import argparse
import traceback
from pathlib import Path
import sys
import os
from platform import platform
import traceback

from mochi import __version__, IS_PYPY, GE_PYTHON_34, GE_PYTHON_33
from mochi.parser import lex, REPL_CONTINUE, ParsingError
from .builtins import current_error_port, eval_sexp_str, eval_tokens
from mochi.parser import lex, REPL_CONTINUE
from .global_env import global_env
from .translation import syntax_table, global_scope, translator

Expand Down Expand Up @@ -104,7 +104,12 @@ def interact(show_tokens=False):
continuation_flag = False
buffer = ''
continue
eval_tokens(tokens)
try:
eval_tokens(tokens)
except ParsingError as e:
print(e, file=current_error_port)
except Exception:
traceback.print_exc(file=current_error_port)


def init():
Expand Down Expand Up @@ -183,16 +188,21 @@ def parse_args():
def main():
args = parse_args()
if args.file:
if args.compile:
output_code(compile_file(args.file, optimize=2, show_tokens=args.tokens))
elif args.execute_compiled_file:
execute_compiled_file(args.file)
elif args.pyc_compile:
pyc_compile_monkeypatch(in_file_name=args.file, show_tokens=args.tokens)
elif args.pyc_compile_no_monkeypatch:
pyc_compile_no_monkeypatch(in_file_name=args.file, show_tokens=args.tokens)
else:
load_file(args.file, global_env)
try:
if args.compile:
output_code(compile_file(args.file, optimize=2, show_tokens=args.tokens))
elif args.execute_compiled_file:
execute_compiled_file(args.file)
elif args.pyc_compile:
pyc_compile_monkeypatch(in_file_name=args.file, show_tokens=args.tokens)
elif args.pyc_compile_no_monkeypatch:
pyc_compile_no_monkeypatch(in_file_name=args.file, show_tokens=args.tokens)
else:
load_file(args.file, global_env)
except ParsingError as e:
print(e, file=sys.stderr)
except Exception:
traceback.print_exc(file=sys.stderr)
sys.exit(0)
else:
interact(args.tokens)
Expand Down
8 changes: 4 additions & 4 deletions mochi/core/translation.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
from os import chdir
from os.path import normpath, abspath

from mochi import GE_PYTHON_34, IS_PYPY
from mochi.parser import Symbol, Keyword, parse, lex, get_temp_name
from .utils import issequence_except_str
from .constants import *
from .exceptions import MochiSyntaxError, DuplicatedDefError
from .global_env import global_env
from mochi import GE_PYTHON_34, IS_PYPY
from mochi.parser import Symbol, Keyword, parse, lex, get_temp_name


if GE_PYTHON_34:
Expand Down Expand Up @@ -104,7 +104,7 @@ def translate_file(self, filename, show_tokens=False):
body = []
self.filename = filename
with open(filename, 'r') as f:
sexps = parse(lex(f.read(), debug=show_tokens))
sexps = parse(lex(f.read(), debug=show_tokens), filename)
chdir(normpath(str(Path(filename).parent)))
for sexp in sexps:
if isinstance(sexp, MutableSequence):
Expand All @@ -120,7 +120,7 @@ def translate_loaded_file(self, filename, show_tokens=False):
body = []
self.filename = filename
with open(filename, 'r') as f:
sexps = parse(lex(f.read(), debug=show_tokens))
sexps = parse(lex(f.read(), debug=show_tokens), filename)
for sexp in sexps:
if isinstance(sexp, MutableSequence):
sexp = tuple_it(sexp)
Expand Down
4 changes: 2 additions & 2 deletions mochi/parser/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
from mochi.parser.lexer import lex, REPL_CONTINUE
from mochi.parser.parser import parse, Symbol, Keyword, get_temp_name
from .lexer import lex, REPL_CONTINUE
from .parser import parse, Symbol, Keyword, get_temp_name, ParsingError
33 changes: 24 additions & 9 deletions mochi/parser/parser.py
Original file line number Diff line number Diff line change
@@ -1,34 +1,49 @@
import warnings
from collections import Sequence

from rply import ParserGenerator, ParsingError
import rply
from rply import ParserGenerator

from mochi import __version__
from mochi.parser.lexer import lg, klg

name_seq = 0


def get_temp_name():
global name_seq
name_seq += 1
name_symbol = Symbol('_gs%s' % name_seq)
return name_symbol


def parse(lexer):
class ParsingError(Exception):
def __init__(self, file_path, lineno=1, colno=1):
self.file_path = file_path
self.lineno = lineno
self.colno = colno

def __str__(self):
return 'ParsingError: file=' \
+ self.file_path\
+ ' lineno='\
+ str(self.lineno)\
+ ' colno='\
+ str(self.colno)


def parse(lexer, filename="<string>"):
try:
with warnings.catch_warnings():
warnings.simplefilter('ignore')
return pg.build().parse(lexer)
except ParsingError as e:
except rply.errors.ParsingError as e:
source_pos = e.getsourcepos()
if source_pos is None:
print('')
raise ParsingError(filename)
else:
print('ParsingError: lineno='
+ str(source_pos.lineno)
+ ' colno='
+ str(source_pos.colno))
raise ParsingError(filename,
source_pos.lineno,
source_pos.colno)


class Symbol(object):
Expand Down

0 comments on commit 1df2c01

Please sign in to comment.