add exponentation in the bitcode lexer
This commit is contained in:
parent
14846e56ae
commit
053c1ebfaf
|
@ -78,7 +78,7 @@ AD P - - -
|
|||
AE C - - -
|
||||
C0 - Yes Yes Yes
|
||||
C8 ⌋ - - -
|
||||
C9 ^( - - -
|
||||
C9 ^( Yes Yes -
|
||||
CA [x]√( - - -
|
||||
D0 ) Yes Yes Yes
|
||||
D4 ⁻¹ - - -
|
||||
|
|
|
@ -63,6 +63,7 @@ class T(enum.IntEnum):
|
|||
MINUS = 0xA7
|
||||
STAR = 0xA8
|
||||
SLASH = 0xA9
|
||||
EXP = 0xC9
|
||||
BANG = 0xD8
|
||||
|
||||
# Tokens with parameters
|
||||
|
|
|
@ -27,6 +27,11 @@ class Parser:
|
|||
|
||||
cond -> expr REL expr
|
||||
expr -> factor | factor + expr | factor - expr
|
||||
factor -> chunk | chunk * factor | chunk / factor
|
||||
chunk -> power+
|
||||
power -> atom | atom "^(" expr ")"
|
||||
atom -> const | var | "(" expr ")" | FUN( funargs ")"
|
||||
|
||||
factor -> atom | atom * factor | atom / factor
|
||||
atom -> const (var | "(" expr ")" | FUN funargs ")")* |
|
||||
(var | "(" expr ")" | FUN funargs ")")+
|
||||
|
@ -201,20 +206,20 @@ class Parser:
|
|||
if t.type == T.MINUS:
|
||||
f.append(Node(N.MINUS, self.factor()))
|
||||
|
||||
# factor -> atom | atom * factor | atom / factor
|
||||
# factor -> chunk | chunk * factor | chunk / factor
|
||||
def factor(self):
|
||||
atom = self.atom()
|
||||
chunk = self.chunk()
|
||||
t = self.expect(T.STAR, T.SLASH, optional=True)
|
||||
|
||||
if t is None:
|
||||
return atom
|
||||
return chunk
|
||||
if t.type == T.STAR:
|
||||
return Node(N.MUL, atom, self.factor())
|
||||
return Node(N.MUL, chunk, self.factor())
|
||||
if t.type == T.SLASH:
|
||||
return Node(N.DIV, atom, self.factor())
|
||||
return Node(N.DIV, chunk, self.factor())
|
||||
|
||||
# atom -> const (VAR | "(" expr ")")* | (VAR | "(" expr ")")+
|
||||
def atom(self):
|
||||
# chunk -> power+
|
||||
def chunk(self):
|
||||
factors = []
|
||||
|
||||
# Initial sign
|
||||
|
@ -224,37 +229,64 @@ class Parser:
|
|||
self.expect(T.MINUS)
|
||||
factors.append(Node(N.CONST, -1))
|
||||
|
||||
# Optional constant
|
||||
if self.la.type == T.CONST:
|
||||
factors.append(self.const())
|
||||
|
||||
while 1:
|
||||
lat = self.la.type
|
||||
|
||||
if lat == T.VAR:
|
||||
factors.append(self.var())
|
||||
elif lat == T.LPAR:
|
||||
self.expect(T.LPAR)
|
||||
factors.append(self.expr())
|
||||
|
||||
# Allow a parenthesis to be removed at the end of a parameter
|
||||
optional = (self.la.type == T.PARAM)
|
||||
self.expect(T.RPAR, optional=optional)
|
||||
|
||||
elif lat == T.FUN:
|
||||
name = self.expect(T.FUN).args[0]
|
||||
a = self.funargs()
|
||||
|
||||
# Allow a parenthesis to be removed at the end of a parameter
|
||||
optional = (self.la.type == T.PARAM)
|
||||
self.expect(T.RPAR, optional=optional)
|
||||
|
||||
factors.append(Node(N.FUN, name, a))
|
||||
else:
|
||||
optional = len(factors) > 0
|
||||
f = self.power(optional=optional)
|
||||
if f is None:
|
||||
break
|
||||
factors.append(f)
|
||||
|
||||
return Node(N.MUL, *factors)
|
||||
|
||||
# power -> atom | atom "^(" expr ")"
|
||||
def power(self, optional=False):
|
||||
a = self.atom(optional=optional)
|
||||
if a is None:
|
||||
return None
|
||||
|
||||
if self.expect(T.EXP, optional=True) is not None:
|
||||
e = self.expr()
|
||||
|
||||
# Allow a parenthesis to be removed at the end of a parameter
|
||||
optional = (self.la.type == T.PARAM)
|
||||
self.expect(T.RPAR, optional=optional)
|
||||
return Node(N.EXP, a, e)
|
||||
|
||||
return a
|
||||
|
||||
# atom -> const | var | "(" expr ")" | FUN( funargs ")"
|
||||
def atom(self, optional=False):
|
||||
lat = self.la.type
|
||||
|
||||
if lat == T.CONST:
|
||||
return self.const()
|
||||
|
||||
if lat == T.VAR:
|
||||
return self.var()
|
||||
|
||||
if lat == T.LPAR:
|
||||
self.expect(T.LPAR)
|
||||
e = self.expr()
|
||||
|
||||
# Allow a parenthesis to be removed at the end of a parameter
|
||||
optional = (self.la.type == T.PARAM)
|
||||
self.expect(T.RPAR, optional=optional)
|
||||
return e
|
||||
|
||||
if lat == T.FUN:
|
||||
name = self.expect(T.FUN).args[0]
|
||||
a = self.funargs()
|
||||
|
||||
# Allow a parenthesis to be removed at the end of a parameter
|
||||
optional = (self.la.type == T.PARAM)
|
||||
self.expect(T.RPAR, optional=optional)
|
||||
|
||||
return Node(N.FUN, name, a)
|
||||
|
||||
if not optional:
|
||||
raise Exception("Empty atom")
|
||||
return None
|
||||
|
||||
# funargs -> expr | expr; funargs
|
||||
def funargs(self):
|
||||
a = [self.expr()]
|
||||
|
|
Loading…
Reference in New Issue