Commit 2d9ca51e authored by Taddeus Kroes's avatar Taddeus Kroes

Merge branch 'master' of kompiler.org:trs

parents f057cada 6c7eb676
......@@ -20,6 +20,8 @@ from node import TYPE_OPERATOR, OP_COMMA
from rules import RULES
from possibilities import filter_duplicates, pick_suggestion, apply_suggestion
import Queue
# Check for n-ary operator in child nodes
def combine(op, op_type, *nodes):
......@@ -74,16 +76,31 @@ class Parser(BisonParser):
self.timeout = kwargs.get('timeout', 0)
self.possibilities = self.last_possibilities = []
self.read_buffer = ''
self.read_queue = Queue.Queue()
# Override default read method with a version that prompts for input.
def read(self, nbytes):
if self.file == sys.stdin and self.file.closed:
return ''
if not self.read_buffer and not self.read_queue.empty():
self.read_buffer = self.read_queue.get_nowait() + '\n'
if self.read_buffer:
read_buffer = self.read_buffer[:nbytes]
self.read_buffer = self.read_buffer[nbytes:]
return read_buffer
try:
return raw_input('>>> ' if self.interactive else '') + '\n'
read_buffer = raw_input('>>> ' if self.interactive else '') + '\n'
except EOFError:
return ''
self.read_buffer = read_buffer[nbytes:]
return read_buffer[:nbytes]
def hook_read_before(self):
if self.possibilities:
if self.interactive: # pragma: nocover
......@@ -95,14 +112,17 @@ class Parser(BisonParser):
if self.interactive: # pragma: nocover
print ' ' + '\n '.join(map(str, items))
self.possibilities = []
def hook_read_after(self, data):
"""
This hook will be called when the read() method returned. The data
argument points to the data read by the read() method. This hook
function should return the data to be used by the parser.
"""
if not data.strip():
return data
self.possibilities = []
import re
# TODO: remove this quick preprocessing hack. This hack enables
......@@ -187,7 +207,6 @@ class Parser(BisonParser):
input :
| input line
"""
if option == 1:
# Interactive mode is enabled if the term rewriting system is used
# as a shell. In that case, it is useful that the shell prints the
......@@ -207,20 +226,22 @@ class Parser(BisonParser):
| REWRITE NEWLINE
| RAISE NEWLINE
"""
if option in [1, 2]:
if option in [1, 2]: # rule: EXP NEWLINE | DEBUG NEWLINE
return values[0]
if option == 3:
if option == 3: # rule: HINT NEWLINE
print pick_suggestion(self.last_possibilities)
return
if option == 4:
if option == 4: # rule: POSSIBILITIES NEWLINE
print '\n'.join(map(str, self.last_possibilities))
return
if option == 5:
if option == 5: # rule: REWRITE NEWLINE
suggestion = pick_suggestion(self.last_possibilities)
return apply_suggestion(suggestion)
expression = apply_suggestion(suggestion)
self.read_queue.put_nowait(str(expression))
return expression
if option == 6:
raise RuntimeError('on_line: exception raised')
......
......@@ -4,6 +4,9 @@ from src.possibilities import MESSAGES, Possibility as P, filter_duplicates
from src.rules.numerics import add_numerics
from tests.test_rules_poly import tree
from src.parser import Parser
from tests.parser import ParserWrapper
def dummy_handler(root, args): # pragma: nocover
pass
......@@ -36,6 +39,36 @@ class TestPossibilities(unittest.TestCase):
assert self.p0 == P(self.n, dummy_handler, (self.l1, self.l2))
assert self.p0 != self.p1
def test_multiple_input(self):
parser = ParserWrapper(Parser)
parser.run(['1+2', '3+4'])
possibilities = parser.parser.possibilities
self.assertEqual('\n'.join([repr(pos) for pos in possibilities]),
'<Possibility root="3 + 4" handler=add_numerics' \
' args=(3, 4, 3, 4)>')
def test_multiple_runs(self):
parser = ParserWrapper(Parser)
parser.run(['1+2'])
possibilities = parser.parser.possibilities
self.assertEqual('\n'.join([repr(pos) for pos in possibilities]),
'<Possibility root="1 + 2" handler=add_numerics' \
' args=(1, 2, 1, 2)>')
# Keep previous possibilities (skip whitespace lines)
parser.run(['', ' '])
possibilities = parser.parser.possibilities
self.assertEqual('\n'.join([repr(pos) for pos in possibilities]),
'<Possibility root="1 + 2" handler=add_numerics' \
' args=(1, 2, 1, 2)>')
# Overwrite previous possibilities with new ones
parser.run(['3+4'])
possibilities = parser.parser.possibilities
self.assertEqual('\n'.join([repr(pos) for pos in possibilities]),
'<Possibility root="3 + 4" handler=add_numerics' \
' args=(3, 4, 3, 4)>')
def test_filter_duplicates(self):
a, b = ab = tree('a + b')
p0 = P(a, dummy_handler, (1, 2))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment