September Morn Update
This commit is contained in:
parent
4e2d22a71d
commit
aac6731f2c
6856 changed files with 141342 additions and 21127 deletions
1
Task/Parsing-Shunting-yard-algorithm/00META.yaml
Normal file
1
Task/Parsing-Shunting-yard-algorithm/00META.yaml
Normal file
|
|
@ -0,0 +1 @@
|
|||
--- {}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
@ -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
|
||||
Loading…
Add table
Add a link
Reference in a new issue