diff --git a/data.py b/data.py
index a8b704f..5008fdd 100644
--- a/data.py
+++ b/data.py
@@ -71,28 +71,44 @@ class NothingClass(object):
Nothing = NothingClass()
class Unknown(object):
- def __init__(self,name='',add=True):
+ def __init__(self,name='',add=True,value=None):
self.name = name
if add:
- unknowns[name] = None
+ unknowns[name] = value
def __repr__(self):
return self.name
def __add__(self,e):
+ if is_number(e) and e==0:
+ return self
return Expr('+',self,e)
def __sub__(self,e):
return self + Expr('*',-1,e)
def __mul__(self,e):
+ if is_number(e) and e==1:
+ return self
return Expr('*',self,e)
+
+ def __pow__(self,e):
+ if is_number(e) and e==1.0:
+ return self
+ return Expr('^', self,e)
+
+ def __div__(self,e):
+ if is_number(e) and e==1:
+ return self
+ return Expr('/',self,e)
class Const(float):
def __init__(self,x):
float.__init__(self,x)
def __add__(self,e):
+ if self == 0:
+ return e
if is_number(e):
return float.__add__(self,e)
if is_nothing(e):
@@ -112,6 +128,8 @@ class Const(float):
return self + Expr('*',-1,e)
def __mul__(self,e):
+ if self == 1.0:
+ return e
if is_number(e):
return float.__mul__(self,e)
if is_nothing(e):
@@ -147,11 +165,11 @@ def line_by_two_points(A,B):
class Point(object):
def __init__(self,name,x,y):
- if isinstance(x, Unknown):
+ if isinstance(x, Unknown) and not x.name:
self.x = Unknown(name+'x')
else:
self.x = x
- if isinstance(y, Unknown):
+ if isinstance(y, Unknown) and not y.name:
self.y = Unknown(name+'y')
else:
self.y = y
@@ -321,7 +339,10 @@ class Expr(object):
return Expr('+',self,e)
def __sub__(self,e):
- return self + Expr('*',-1,e)
+ return self + Expr('*',Const(-1),e)
+
+ def __neg__(self):
+ return Expr('*',Const(-1),self)
def __mul__(self,e):
if is_number(e):
diff --git a/lexer.py b/lexer.py
index a87aaf7..e5c0d02 100644
--- a/lexer.py
+++ b/lexer.py
@@ -1,13 +1,13 @@
from ply import lex
-from data import Const
+from data import Const, Unknown
-tokens = ('POINT','SEGMENT', 'IN', 'PARAL', 'PERP', 'EQ', 'PARENL', 'PARENR', 'COMMA','NUMBER')
+tokens = ('POINT','SEGMENT', 'IN', 'PARAL', 'PERP', 'EQ', 'PARENL', 'PARENR', 'COMMA','NUMBER','VAR')
t_POINT = '[A-Z]'
t_SEGMENT = '[A-Z][A-Z]'
-t_IN = 'in'
+t_IN = '<-'
t_PARAL = '\|\|'
t_PERP = '_\|_'
t_EQ = '='
@@ -24,4 +24,9 @@ def t_NUMBER(t):
t.value = Const(t.value)
return t
+def t_VAR(t):
+ "[a-z][0-9]?"
+ t.value = Unknown(t.value,value=Unknown(t.value))
+ return t
+
lex.lex()
diff --git a/parser.out b/parser.out
index 3c78c00..9c8f278 100644
--- a/parser.out
+++ b/parser.out
@@ -10,27 +10,31 @@ Rule 2 statement -> SEGMENT PARAL SEGMENT
Rule 3 statement -> SEGMENT PERP SEGMENT
Rule 4 statement -> POINT IN SEGMENT
Rule 5 statement -> SEGMENT EQ SEGMENT
-Rule 6 statement -> SEGMENT EQ NUMBER
-Rule 7 statement -> POINT PARENL NUMBER COMMA NUMBER PARENR
+Rule 6 statement -> SEGMENT EQ value
+Rule 7 statement -> POINT PARENL value COMMA value PARENR
+Rule 8 value -> NUMBER
+Rule 9 value -> VAR
Terminals, with rules where they appear
COMMA : 7
EQ : 5 6
IN : 4
-NUMBER : 6 7 7
+NUMBER : 8
PARAL : 2
PARENL : 7
PARENR : 7
PERP : 3
POINT : 4 7
SEGMENT : 2 2 3 3 4 5 5 6
+VAR : 9
error :
Nonterminals, with rules where they appear
generic : 0
statement : 1
+value : 6 7 7
Parsing method: LALR
@@ -44,8 +48,8 @@ state 0
(3) statement -> . SEGMENT PERP SEGMENT
(4) statement -> . POINT IN SEGMENT
(5) statement -> . SEGMENT EQ SEGMENT
- (6) statement -> . SEGMENT EQ NUMBER
- (7) statement -> . POINT PARENL NUMBER COMMA NUMBER PARENR
+ (6) statement -> . SEGMENT EQ value
+ (7) statement -> . POINT PARENL value COMMA value PARENR
SEGMENT shift and go to state 4
POINT shift and go to state 1
@@ -57,7 +61,7 @@ state 0
state 1
(4) statement -> POINT . IN SEGMENT
- (7) statement -> POINT . PARENL NUMBER COMMA NUMBER PARENR
+ (7) statement -> POINT . PARENL value COMMA value PARENR
IN shift and go to state 5
PARENL shift and go to state 6
@@ -84,7 +88,7 @@ state 4
(2) statement -> SEGMENT . PARAL SEGMENT
(3) statement -> SEGMENT . PERP SEGMENT
(5) statement -> SEGMENT . EQ SEGMENT
- (6) statement -> SEGMENT . EQ NUMBER
+ (6) statement -> SEGMENT . EQ value
PARAL shift and go to state 9
PERP shift and go to state 8
@@ -102,27 +106,35 @@ state 5
state 6
- (7) statement -> POINT PARENL . NUMBER COMMA NUMBER PARENR
+ (7) statement -> POINT PARENL . value COMMA value PARENR
+ (8) value -> . NUMBER
+ (9) value -> . VAR
NUMBER shift and go to state 11
+ VAR shift and go to state 13
+ value shift and go to state 12
state 7
(5) statement -> SEGMENT EQ . SEGMENT
- (6) statement -> SEGMENT EQ . NUMBER
+ (6) statement -> SEGMENT EQ . value
+ (8) value -> . NUMBER
+ (9) value -> . VAR
- SEGMENT shift and go to state 12
- NUMBER shift and go to state 13
+ SEGMENT shift and go to state 14
+ NUMBER shift and go to state 11
+ VAR shift and go to state 13
+ value shift and go to state 15
state 8
(3) statement -> SEGMENT PERP . SEGMENT
- SEGMENT shift and go to state 14
+ SEGMENT shift and go to state 16
@@ -130,7 +142,7 @@ state 9
(2) statement -> SEGMENT PARAL . SEGMENT
- SEGMENT shift and go to state 15
+ SEGMENT shift and go to state 17
@@ -144,64 +156,88 @@ state 10
state 11
- (7) statement -> POINT PARENL NUMBER . COMMA NUMBER PARENR
+ (8) value -> NUMBER .
- COMMA shift and go to state 16
+ $end reduce using rule 8 (value -> NUMBER .)
+ PARENR reduce using rule 8 (value -> NUMBER .)
+ COMMA reduce using rule 8 (value -> NUMBER .)
state 12
- (5) statement -> SEGMENT EQ SEGMENT .
+ (7) statement -> POINT PARENL value . COMMA value PARENR
- $end reduce using rule 5 (statement -> SEGMENT EQ SEGMENT .)
+ COMMA shift and go to state 18
state 13
- (6) statement -> SEGMENT EQ NUMBER .
+ (9) value -> VAR .
- $end reduce using rule 6 (statement -> SEGMENT EQ NUMBER .)
+ $end reduce using rule 9 (value -> VAR .)
+ PARENR reduce using rule 9 (value -> VAR .)
+ COMMA reduce using rule 9 (value -> VAR .)
state 14
- (3) statement -> SEGMENT PERP SEGMENT .
+ (5) statement -> SEGMENT EQ SEGMENT .
- $end reduce using rule 3 (statement -> SEGMENT PERP SEGMENT .)
+ $end reduce using rule 5 (statement -> SEGMENT EQ SEGMENT .)
state 15
- (2) statement -> SEGMENT PARAL SEGMENT .
+ (6) statement -> SEGMENT EQ value .
- $end reduce using rule 2 (statement -> SEGMENT PARAL SEGMENT .)
+ $end reduce using rule 6 (statement -> SEGMENT EQ value .)
state 16
- (7) statement -> POINT PARENL NUMBER COMMA . NUMBER PARENR
+ (3) statement -> SEGMENT PERP SEGMENT .
- NUMBER shift and go to state 17
+ $end reduce using rule 3 (statement -> SEGMENT PERP SEGMENT .)
state 17
- (7) statement -> POINT PARENL NUMBER COMMA NUMBER . PARENR
+ (2) statement -> SEGMENT PARAL SEGMENT .
- PARENR shift and go to state 18
+ $end reduce using rule 2 (statement -> SEGMENT PARAL SEGMENT .)
state 18
- (7) statement -> POINT PARENL NUMBER COMMA NUMBER PARENR .
+ (7) statement -> POINT PARENL value COMMA . value PARENR
+ (8) value -> . NUMBER
+ (9) value -> . VAR
+
+ NUMBER shift and go to state 11
+ VAR shift and go to state 13
+
+
+ value shift and go to state 19
+
+state 19
+
+ (7) statement -> POINT PARENL value COMMA value . PARENR
+
+ PARENR shift and go to state 20
+
+
+
+state 20
+
+ (7) statement -> POINT PARENL value COMMA value PARENR .
- $end reduce using rule 7 (statement -> POINT PARENL NUMBER COMMA NUMBER PARENR .)
+ $end reduce using rule 7 (statement -> POINT PARENL value COMMA value PARENR .)
diff --git a/parsetab.py b/parsetab.py
index 1b9b4ff..c5eca60 100644
--- a/parsetab.py
+++ b/parsetab.py
@@ -4,9 +4,9 @@
_lr_method = 'LALR'
-_lr_signature = "'K\xe1\xf4\xb9.`<\x83\xcc:]\xa6\xcb\xff\xc5"
+_lr_signature = '\x92\x98\x85\xb9]z\xf7\x14\x8c\xbe\xd7pE\xaeh2'
-_lr_action_items = {'PARENR':([17,],[18,]),'POINT':([0,],[1,]),'EQ':([4,],[7,]),'NUMBER':([6,7,16,],[11,13,17,]),'PARAL':([4,],[9,]),'PERP':([4,],[8,]),'COMMA':([11,],[16,]),'IN':([1,],[5,]),'SEGMENT':([0,5,7,8,9,],[4,10,12,14,15,]),'PARENL':([1,],[6,]),'$end':([2,3,10,12,13,14,15,18,],[0,-1,-4,-5,-6,-3,-2,-7,]),}
+_lr_action_items = {'PARENR':([11,13,19,],[-8,-9,20,]),'POINT':([0,],[1,]),'EQ':([4,],[7,]),'NUMBER':([6,7,18,],[11,11,11,]),'PARAL':([4,],[9,]),'PERP':([4,],[8,]),'COMMA':([11,12,13,],[-8,18,-9,]),'IN':([1,],[5,]),'VAR':([6,7,18,],[13,13,13,]),'SEGMENT':([0,5,7,8,9,],[4,10,14,16,17,]),'PARENL':([1,],[6,]),'$end':([2,3,10,11,13,14,15,16,17,20,],[0,-1,-4,-8,-9,-5,-6,-3,-2,-7,]),}
_lr_action = { }
for _k, _v in _lr_action_items.items():
@@ -15,7 +15,7 @@ for _k, _v in _lr_action_items.items():
_lr_action[_x][_k] = _y
del _lr_action_items
-_lr_goto_items = {'generic':([0,],[2,]),'statement':([0,],[3,]),}
+_lr_goto_items = {'generic':([0,],[2,]),'value':([6,7,18,],[12,15,19,]),'statement':([0,],[3,]),}
_lr_goto = { }
for _k, _v in _lr_goto_items.items():
@@ -32,4 +32,6 @@ _lr_productions = [
('statement',3,'p_statement_eq_s','syntax.py',31),
('statement',3,'p_statement_eq_n','syntax.py',37),
('statement',6,'p_statement_point','syntax.py',43),
+ ('value',1,'p_value_number','syntax.py',48),
+ ('value',1,'p_value_var','syntax.py',52),
]
diff --git a/syntax.py b/syntax.py
index 8d113cd..66ea126 100644
--- a/syntax.py
+++ b/syntax.py
@@ -34,16 +34,23 @@ def p_statement_eq_s(t):
t[0] = c
def p_statement_eq_n(t):
- "statement : SEGMENT EQ NUMBER"
+ "statement : SEGMENT EQ value"
c = Condition(COND_EQ, segment(t[1]), t[3])
conditions.append(c)
t[0] = c
def p_statement_point(t):
- "statement : POINT PARENL NUMBER COMMA NUMBER PARENR"
+ "statement : POINT PARENL value COMMA value PARENR"
p = Point(t[1],t[3],t[5])
points[t[1]] = p
- return p
+
+def p_value_number(t):
+ "value : NUMBER"
+ t[0] = t[1]
+
+def p_value_var(t):
+ "value : VAR"
+ t[0] = t[1]
yacc.yacc()