June 2018 Update
This commit is contained in:
parent
ba8067c3b7
commit
22f33d4004
5278 changed files with 84726 additions and 14379 deletions
|
|
@ -4,11 +4,11 @@ import extensions'text.
|
|||
|
||||
class Token
|
||||
{
|
||||
object theValue.
|
||||
object theValue.
|
||||
|
||||
object rprop level :: theLevel.
|
||||
int rprop level :: theLevel.
|
||||
|
||||
constructor new level:aLevel
|
||||
constructor new(int aLevel)
|
||||
[
|
||||
theValue := StringWriter new.
|
||||
theLevel := aLevel + 9.
|
||||
|
|
@ -19,16 +19,16 @@ class Token
|
|||
theValue << aChar.
|
||||
]
|
||||
|
||||
number = theValue get; toReal.
|
||||
number = theValue toReal.
|
||||
}
|
||||
|
||||
class Node
|
||||
{
|
||||
object prop left :: theLeft.
|
||||
object prop right :: theRight.
|
||||
object rprop level :: theLevel.
|
||||
int rprop level :: theLevel.
|
||||
|
||||
constructor new level:aLevel
|
||||
constructor new(int aLevel)
|
||||
[
|
||||
theLevel := aLevel.
|
||||
]
|
||||
|
|
@ -36,42 +36,42 @@ class Node
|
|||
|
||||
class SummaryNode :: Node
|
||||
{
|
||||
constructor new level:aLevel
|
||||
<= new level(aLevel + 1).
|
||||
constructor new(int aLevel)
|
||||
<= new(aLevel + 1).
|
||||
|
||||
number = theLeft number + theRight number.
|
||||
}
|
||||
|
||||
class DifferenceNode :: Node
|
||||
{
|
||||
constructor new level:aLevel
|
||||
<= new level(aLevel + 1).
|
||||
constructor new(int aLevel)
|
||||
<= new(aLevel + 1).
|
||||
|
||||
number = theLeft number - theRight number.
|
||||
}
|
||||
|
||||
class ProductNode :: Node
|
||||
{
|
||||
constructor new level:aLevel
|
||||
<= new level(aLevel + 2).
|
||||
constructor new(int aLevel)
|
||||
<= new(aLevel + 2).
|
||||
|
||||
number = theLeft number * theRight number.
|
||||
}
|
||||
|
||||
class FractionNode :: Node
|
||||
{
|
||||
constructor new level:aLevel
|
||||
<= new level(aLevel + 2).
|
||||
constructor new(int aLevel)
|
||||
<= new(aLevel + 2).
|
||||
|
||||
number = theLeft number / theRight number.
|
||||
}
|
||||
|
||||
class Expression
|
||||
{
|
||||
object rprop level :: theLevel.
|
||||
int rprop level :: theLevel.
|
||||
object prop top :: theTop.
|
||||
|
||||
constructor new level:aLevel
|
||||
constructor new(int aLevel)
|
||||
[
|
||||
theLevel := aLevel
|
||||
]
|
||||
|
|
@ -83,101 +83,101 @@ class Expression
|
|||
number => theTop.
|
||||
}
|
||||
|
||||
operatorState = (:ch)
|
||||
operatorState : ch
|
||||
[
|
||||
ch =>
|
||||
$40 [ // (
|
||||
^ closure newBracket; gotoStarting
|
||||
^ target newBracket; gotoStarting
|
||||
];
|
||||
! [
|
||||
^ closure newToken; append:ch; gotoToken
|
||||
^ target newToken; append:ch; gotoToken
|
||||
].
|
||||
].
|
||||
]
|
||||
|
||||
tokenState = (:ch)
|
||||
tokenState : ch
|
||||
[
|
||||
ch =>
|
||||
$41 [ // )
|
||||
^ closure closeBracket; gotoToken
|
||||
^ target closeBracket; gotoToken
|
||||
];
|
||||
$42 [ // *
|
||||
^ closure newProduct; gotoOperator
|
||||
^ target newProduct; gotoOperator
|
||||
];
|
||||
$43 [ // +
|
||||
^ closure newSummary; gotoOperator
|
||||
^ target newSummary; gotoOperator
|
||||
];
|
||||
$45 [ // -
|
||||
^ closure newDifference; gotoOperator
|
||||
^ target newDifference; gotoOperator
|
||||
];
|
||||
$47 [ // /
|
||||
^ closure newFraction; gotoOperator
|
||||
^ target newFraction; gotoOperator
|
||||
];
|
||||
! [
|
||||
^ closure append:ch
|
||||
^ target append:ch
|
||||
].
|
||||
].
|
||||
]
|
||||
|
||||
startState = (:ch)
|
||||
startState : ch
|
||||
[
|
||||
ch =>
|
||||
$40 [ // (
|
||||
^ closure newBracket; gotoStarting
|
||||
^ target newBracket; gotoStarting
|
||||
];
|
||||
$45 [ // -
|
||||
^ closure newToken; append literal:"0"; newDifference; gotoOperator
|
||||
^ target newToken; append:"0"; newDifference; gotoOperator
|
||||
];
|
||||
! [
|
||||
^ closure newToken; append:ch; gotoToken
|
||||
^ target newToken; append:ch; gotoToken
|
||||
].
|
||||
].
|
||||
]
|
||||
|
||||
class Scope
|
||||
{
|
||||
object theState.
|
||||
object theLevel.
|
||||
int theLevel.
|
||||
object theParser.
|
||||
object theToken.
|
||||
object theExpression.
|
||||
|
||||
constructor new parser:aParser
|
||||
constructor new:aParser
|
||||
[
|
||||
theState := startState.
|
||||
theLevel := 0.
|
||||
theExpression := Expression new level:0.
|
||||
theExpression := Expression new(0).
|
||||
theParser := aParser.
|
||||
]
|
||||
|
||||
newToken
|
||||
[
|
||||
theToken := theParser appendToken expression:theExpression level:theLevel.
|
||||
theToken := theParser appendToken(theExpression, theLevel).
|
||||
]
|
||||
|
||||
newSummary
|
||||
[
|
||||
theToken := nil.
|
||||
|
||||
theParser appendSummary expression:theExpression level:theLevel.
|
||||
theParser appendSummary(theExpression, theLevel).
|
||||
]
|
||||
|
||||
newDifference
|
||||
[
|
||||
theToken := nil.
|
||||
|
||||
theParser appendDifference expression:theExpression level:theLevel
|
||||
theParser appendDifference(theExpression, theLevel)
|
||||
]
|
||||
|
||||
newProduct
|
||||
[
|
||||
theToken := nil.
|
||||
|
||||
theParser appendProduct expression:theExpression level:theLevel
|
||||
theParser appendProduct(theExpression, theLevel)
|
||||
]
|
||||
|
||||
newFraction
|
||||
[
|
||||
theToken := nil.
|
||||
|
||||
theParser appendFraction expression:theExpression level:theLevel
|
||||
theParser appendFraction(theExpression, theLevel)
|
||||
]
|
||||
|
||||
newBracket
|
||||
|
|
@ -186,7 +186,7 @@ class Scope
|
|||
|
||||
theLevel := theLevel + 10.
|
||||
|
||||
theParser appendSubexpression expression:theExpression level:theLevel.
|
||||
theParser appendSubexpression(theExpression, theLevel).
|
||||
]
|
||||
|
||||
closeBracket
|
||||
|
|
@ -204,7 +204,7 @@ class Scope
|
|||
[ InvalidArgumentException new:"Invalid expression"; raise ]
|
||||
]
|
||||
|
||||
append literal:aLiteral
|
||||
append(literal aLiteral)
|
||||
[
|
||||
aLiteral forEach(:ch)[ self append:ch ]
|
||||
]
|
||||
|
|
@ -231,63 +231,63 @@ class Scope
|
|||
|
||||
class Parser
|
||||
{
|
||||
appendToken expression:anExpression level:aLevel
|
||||
appendToken(object anExpression, int aLevel)
|
||||
[
|
||||
var aToken := Token new level:aLevel.
|
||||
var aToken := Token new(aLevel).
|
||||
|
||||
anExpression set top:($self append last(anExpression top) new:aToken).
|
||||
anExpression top := self append(anExpression top, aToken).
|
||||
|
||||
^ aToken
|
||||
]
|
||||
|
||||
appendSummary expression:anExpression level:aLevel
|
||||
appendSummary(object anExpression, int aLevel)
|
||||
[
|
||||
anExpression set top($self append last(anExpression top) new(SummaryNode new level:aLevel)).
|
||||
anExpression top := self append(anExpression top, SummaryNode new(aLevel)).
|
||||
]
|
||||
|
||||
appendDifference expression:anExpression level:aLevel
|
||||
appendDifference(object anExpression, int aLevel)
|
||||
[
|
||||
anExpression set top($self append last(anExpression top) new(DifferenceNode new level:aLevel)).
|
||||
anExpression top := self append(anExpression top, DifferenceNode new(aLevel)).
|
||||
]
|
||||
|
||||
appendProduct expression:anExpression level:aLevel
|
||||
appendProduct(object anExpression, int aLevel)
|
||||
[
|
||||
anExpression set top($self append last(anExpression top) new(ProductNode new level:aLevel)).
|
||||
anExpression top := self append(anExpression top, ProductNode new(aLevel)).
|
||||
]
|
||||
|
||||
appendFraction expression:anExpression level:aLevel
|
||||
appendFraction(object anExpression, int aLevel)
|
||||
[
|
||||
anExpression set top($self append last(anExpression top) new(FractionNode new level:aLevel))
|
||||
anExpression top := self append(anExpression top, FractionNode new(aLevel))
|
||||
]
|
||||
|
||||
appendSubexpression expression:anExpression level:aLevel
|
||||
appendSubexpression(object anExpression, int aLevel)
|
||||
[
|
||||
anExpression set top($self append last(anExpression top) new(Expression new level:aLevel)).
|
||||
anExpression top := self append(anExpression top, Expression new(aLevel)).
|
||||
]
|
||||
|
||||
append last:aLastNode new:aNewNode
|
||||
append(object aLastNode, object aNewNode)
|
||||
[
|
||||
if($nil == aLastNode)
|
||||
if(nil == aLastNode)
|
||||
[ ^ aNewNode ].
|
||||
|
||||
if (aNewNode level <= aLastNode level)
|
||||
[ aNewNode set left:aLastNode. ^ aNewNode ].
|
||||
[ aNewNode left := aLastNode. ^ aNewNode ].
|
||||
|
||||
var aParent := aLastNode.
|
||||
var aCurrent := aLastNode right.
|
||||
while (($nil != aCurrent) && $(aNewNode level > aCurrent level))
|
||||
while ((nil != aCurrent) && (aNewNode level > aCurrent level))
|
||||
[ aParent := aCurrent. aCurrent := aCurrent right. ].
|
||||
|
||||
if ($nil == aCurrent)
|
||||
[ aParent set right:aNewNode. ];
|
||||
[ aNewNode set left:aCurrent. aParent set right:aNewNode ].
|
||||
if (nil == aCurrent)
|
||||
[ aParent right := aNewNode. ];
|
||||
[ aNewNode left := aCurrent. aParent right := aNewNode ].
|
||||
|
||||
^ aLastNode
|
||||
]
|
||||
|
||||
run : aText
|
||||
[
|
||||
var aScope := Scope new parser:$self.
|
||||
var aScope := Scope new(self).
|
||||
|
||||
aText forEach(:ch)[ aScope eval:ch ].
|
||||
|
||||
|
|
@ -295,9 +295,9 @@ class Parser
|
|||
]
|
||||
}
|
||||
|
||||
program =
|
||||
public program =
|
||||
[
|
||||
var aText := String new.
|
||||
var aText := StringWriter new.
|
||||
var aParser := Parser new.
|
||||
|
||||
$(console readLine; saveTo:aText; length > 0) doWhile:
|
||||
|
|
|
|||
|
|
@ -0,0 +1,86 @@
|
|||
// version 1.2.10
|
||||
|
||||
/* if string is empty, returns zero */
|
||||
fun String.toDoubleOrZero() = this.toDoubleOrNull() ?: 0.0
|
||||
|
||||
fun multiply(s: String): String {
|
||||
val b = s.split('*').map { it.toDoubleOrZero() }
|
||||
return (b[0] * b[1]).toString()
|
||||
}
|
||||
|
||||
fun divide(s: String): String {
|
||||
val b = s.split('/').map { it.toDoubleOrZero() }
|
||||
return (b[0] / b[1]).toString()
|
||||
}
|
||||
|
||||
fun add(s: String): String {
|
||||
var t = s.replace(Regex("""^\+"""), "").replace(Regex("""\++"""), "+")
|
||||
val b = t.split('+').map { it.toDoubleOrZero() }
|
||||
return (b[0] + b[1]).toString()
|
||||
}
|
||||
|
||||
fun subtract(s: String): String {
|
||||
var t = s.replace(Regex("""(\+-|-\+)"""), "-")
|
||||
if ("--" in t) return add(t.replace("--", "+"))
|
||||
val b = t.split('-').map { it.toDoubleOrZero() }
|
||||
return (if (b.size == 3) -b[1] - b[2] else b[0] - b[1]).toString()
|
||||
}
|
||||
|
||||
fun evalExp(s: String): String {
|
||||
var t = s.replace(Regex("""[()]"""), "")
|
||||
val reMD = Regex("""\d+\.?\d*\s*[*/]\s*[+-]?\d+\.?\d*""")
|
||||
val reM = Regex( """\*""")
|
||||
val reAS = Regex("""-?\d+\.?\d*\s*[+-]\s*[+-]?\d+\.?\d*""")
|
||||
val reA = Regex("""\d\+""")
|
||||
|
||||
while (true) {
|
||||
val match = reMD.find(t)
|
||||
if (match == null) break
|
||||
val exp = match.value
|
||||
val match2 = reM.find(exp)
|
||||
t = if (match2 != null)
|
||||
t.replace(exp, multiply(exp))
|
||||
else
|
||||
t.replace(exp, divide(exp))
|
||||
}
|
||||
|
||||
while (true) {
|
||||
val match = reAS.find(t)
|
||||
if (match == null) break
|
||||
val exp = match.value
|
||||
val match2 = reA.find(exp)
|
||||
t = if (match2 != null)
|
||||
t.replace(exp, add(exp))
|
||||
else
|
||||
t.replace(exp, subtract(exp))
|
||||
}
|
||||
|
||||
return t
|
||||
}
|
||||
|
||||
fun evalArithmeticExp(s: String): Double {
|
||||
var t = s.replace(Regex("""\s"""), "").replace("""^\+""", "")
|
||||
val rePara = Regex("""\([^()]*\)""")
|
||||
while(true) {
|
||||
val match = rePara.find(t)
|
||||
if (match == null) break
|
||||
val exp = match.value
|
||||
t = t.replace(exp, evalExp(exp))
|
||||
}
|
||||
return evalExp(t).toDoubleOrZero()
|
||||
}
|
||||
|
||||
fun main(arsg: Array<String>) {
|
||||
listOf(
|
||||
"2+3",
|
||||
"2+3/4",
|
||||
"2*3-4",
|
||||
"2*(3+4)+5/6",
|
||||
"2 * (3 + (4 * 5 + (6 * 7) * 8) - 9) * 10",
|
||||
"2*-3--4+-0.25",
|
||||
"-4 - 3",
|
||||
"((((2))))+ 3 * 5",
|
||||
"1 + 2 * (3 + (4 * 5 + 6 * 7 * 8) - 9) / 10",
|
||||
"1 + 2*(3 - 2*(3 - 2)*((2 - 4)*5 - 22/(7 + 2*(3 - 1)) - 1)) + 1"
|
||||
).forEach { println("$it = ${evalArithmeticExp(it)}") }
|
||||
}
|
||||
44
Task/Arithmetic-evaluation/Perl-6/arithmetic-evaluation.pl6
Normal file
44
Task/Arithmetic-evaluation/Perl-6/arithmetic-evaluation.pl6
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
sub ev (Str $s --> Numeric) {
|
||||
|
||||
grammar expr {
|
||||
token TOP { ^ <sum> $ }
|
||||
token sum { <product> (('+' || '-') <product>)* }
|
||||
token product { <factor> (('*' || '/') <factor>)* }
|
||||
token factor { <unary_minus>? [ <parens> || <literal> ] }
|
||||
token unary_minus { '-' }
|
||||
token parens { '(' <sum> ')' }
|
||||
token literal { \d+ ['.' \d+]? || '.' \d+ }
|
||||
}
|
||||
|
||||
my sub minus ($b) { $b ?? -1 !! +1 }
|
||||
|
||||
my sub sum ($x) {
|
||||
[+] flat product($x<product>), map
|
||||
{ minus($^y[0] eq '-') * product $^y<product> },
|
||||
|($x[0] or [])
|
||||
}
|
||||
|
||||
my sub product ($x) {
|
||||
[*] flat factor($x<factor>), map
|
||||
{ factor($^y<factor>) ** minus($^y[0] eq '/') },
|
||||
|($x[0] or [])
|
||||
}
|
||||
|
||||
my sub factor ($x) {
|
||||
minus($x<unary_minus>) * ($x<parens>
|
||||
?? sum $x<parens><sum>
|
||||
!! $x<literal>)
|
||||
}
|
||||
|
||||
expr.parse([~] split /\s+/, $s);
|
||||
$/ or fail 'No parse.';
|
||||
sum $/<sum>;
|
||||
|
||||
}
|
||||
|
||||
# Testing:
|
||||
|
||||
say ev '5'; # 5
|
||||
say ev '1 + 2 - 3 * 4 / 5'; # 0.6
|
||||
say ev '1 + 5*3.4 - .5 -4 / -2 * (3+4) -6'; # 25.5
|
||||
say ev '((11+15)*15)* 2 + (3) * -4 *1'; # 768
|
||||
Loading…
Add table
Add a link
Reference in a new issue