September Morn Update

This commit is contained in:
Ingy döt Net 2019-09-12 10:33:56 -07:00
parent 4e2d22a71d
commit aac6731f2c
6856 changed files with 141342 additions and 21127 deletions

View file

@ -0,0 +1 @@
--- {}

View file

@ -0,0 +1,59 @@
#include <iostream>
#include <sstream>
#include <stack>
std::string infixToPostfix(const std::string& infix) {
const std::string ops = "-+/*^";
std::stringstream ss;
std::stack<int> s;
std::stringstream input(infix);
std::string token;
while (std::getline(input, token, ' ')) {
if (token.empty()) {
continue;
}
char c = token[0];
size_t idx = ops.find(c);
// check for operator
if (idx != std::string::npos) {
while (!s.empty()) {
int prec2 = s.top() / 2;
int prec1 = idx / 2;
if (prec2 > prec1 || (prec2 == prec1 && c != '^')) {
ss << ops[s.top()] << ' ';
s.pop();
} else break;
}
s.push(idx);
} else if (c == '(') {
s.push(-2); // -2 stands for '('
} else if (c == ')') {
// until '(' on stack, pop operators.
while (s.top() != -2) {
ss << ops[s.top()] << ' ';
s.pop();
}
s.pop();
} else {
ss << token << ' ';
}
}
while (!s.empty()) {
ss << ops[s.top()] << ' ';
s.pop();
}
return ss.str();
}
int main() {
std::string infix = "3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3";
std::cout << "infix: " << infix << '\n';
std::cout << "postfix: " << infixToPostfix(infix) << '\n';
return 0;
}

View file

@ -99,7 +99,7 @@ int parse(const char *s) {
pat_t *p;
str_tok_t *t, tok;
prec_booster = l_queue = 0;
prec_booster = l_queue = l_stack = 0;
display(s);
while (*s) {
p = match(s, pat_arg, &tok, &s);
@ -152,6 +152,9 @@ re_op: p = match(s, pat_ops, &tok, &s);
display(s);
}
if (p->prec > 0)
fail("unexpected eol", s);
return 1;
}
@ -165,6 +168,7 @@ int main()
"(((((((1+2+3**(4 + 5))))))", /* bad parens */
"a^(b + c/d * .1e5)!", /* unknown op */
"(1**2)**3", /* OK */
"2 + 2 *", /* unexpected eol */
0
};

View file

@ -0,0 +1,45 @@
import tables, strutils, sequtils, strformat
type operator = tuple[prec:int, rassoc:bool]
let ops = newTable[string, operator](
[ ("^", (4, true )),
("*", (3, false)),
("/", (3, false)),
("+", (2, false)),
("-", (2, false)) ])
proc shuntRPN(tokens:seq[string]): string =
var stack: seq[string]
var op:string
for token in tokens:
case token
of "(": stack.add token
of ")":
while stack.len > 0:
op = stack.pop()
if op == "(": break
result &= op & " "
else:
if token in ops:
while stack.len > 0:
op = stack[^1] # peek stack top
if not (op in ops): break
if ops[token].prec > ops[op].prec or (ops[token].rassoc and (ops[token].prec == ops[op].prec)):
break
discard stack.pop()
result &= op & " "
stack.add token
else:
result &= token & " "
echo fmt"""{token:5} {join(stack," "):18} {result:25} """
while stack.len > 0:
result &= stack.pop() & " "
echo fmt""" {join(stack," "):18} {result:25} """
let input = "3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3"
echo &"for infix expression: '{input}' \n", "\nTOKEN OP STACK RPN OUTPUT"
echo "postfix: ", shuntRPN(input.strip.split)

View file

@ -0,0 +1,83 @@
Module Module1
Class SymbolType
Public ReadOnly symbol As String
Public ReadOnly precedence As Integer
Public ReadOnly rightAssociative As Boolean
Public Sub New(symbol As String, precedence As Integer, rightAssociative As Boolean)
Me.symbol = symbol
Me.precedence = precedence
Me.rightAssociative = rightAssociative
End Sub
End Class
ReadOnly Operators As Dictionary(Of String, SymbolType) = New Dictionary(Of String, SymbolType) From
{
{"^", New SymbolType("^", 4, True)},
{"*", New SymbolType("*", 3, False)},
{"/", New SymbolType("/", 3, False)},
{"+", New SymbolType("+", 2, False)},
{"-", New SymbolType("-", 2, False)}
}
Function ToPostfix(infix As String) As String
Dim tokens = infix.Split(" ")
Dim stack As New Stack(Of String)
Dim output As New List(Of String)
Dim Print = Sub(action As String) Console.WriteLine("{0,-4} {1,-18} {2}", action + ":", $"stack[ {String.Join(" ", stack.Reverse())} ]", $"out[ {String.Join(" ", output)} ]")
For Each token In tokens
Dim iv As Integer
Dim op1 As SymbolType
Dim op2 As SymbolType
If Integer.TryParse(token, iv) Then
output.Add(token)
Print(token)
ElseIf Operators.TryGetValue(token, op1) Then
While stack.Count > 0 AndAlso Operators.TryGetValue(stack.Peek(), op2)
Dim c = op1.precedence.CompareTo(op2.precedence)
If c < 0 OrElse Not op1.rightAssociative AndAlso c <= 0 Then
output.Add(stack.Pop())
Else
Exit While
End If
End While
stack.Push(token)
Print(token)
ElseIf token = "(" Then
stack.Push(token)
Print(token)
ElseIf token = ")" Then
Dim top = ""
While stack.Count > 0
top = stack.Pop()
If top <> "(" Then
output.Add(top)
Else
Exit While
End If
End While
If top <> "(" Then
Throw New ArgumentException("No matching left parenthesis.")
End If
Print(token)
End If
Next
While stack.Count > 0
Dim top = stack.Pop()
If Not Operators.ContainsKey(top) Then
Throw New ArgumentException("No matching right parenthesis.")
End If
output.Add(top)
End While
Print("pop")
Return String.Join(" ", output)
End Function
Sub Main()
Dim infix = "3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3"
Console.WriteLine(ToPostfix(infix))
End Sub
End Module