How to Evaluate an Expression

Материал из Поле цифровой дидактики
Версия от 11:33, 21 июля 2022; Patarakin (обсуждение | вклад) (1 версия импортирована)
(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)

This tutorial teaches how to evaluate an expression.

Making the Custom Block

This implementation does not include support for functions or unary negation. This means if you want to calculate -5 * 10 you will have to rephrase it as (0-5) * 10

Variables needed

You will need to create these Variables:

  • i
  • lasttoken
  • token
  • letter
  • result

You will also need to create these Lists:

  • queue
  • stack
  • tokens

Шаблон:Note And a list called operators with these items:

  1. -
  2. +
  3. /
  4. *

Full block

This Project has the script for easy backpacking.

defineevaluateexpressionsetito1Tokenizetheexpressiondeletealloftokensrepeatlengthofexpressionsetlettertoletteriofexpressionsetlasttokentoitemlengthoftokensoftokensif123456.7890containslettertheniflasttoken/1=lasttokenorlasttoken=.thenreplaceitemlengthoftokensoftokenswithjoinlasttokenletterelseaddlettertotokensendelseif()+-/*containsletterthenaddlettertotokensendendenddeleteallofstackShuntingyardalgorithmdeleteallofqueuesetito1repeatlengthoftokenssettokentoitemioftokensiftoken/1=tokenthenaddtokentoqueueendifoperatorscontainstokenthenrepeatuntilitem1ofstack=(orlengthofstack=0oritem#ofitem1ofstackinoperators<item#oftokeninoperatorsadditem1ofstacktoqueuedelete1ofstackendinserttokenat1ofstackendiftoken=(theninserttokenat1ofstackendiftoken=)thenrepeatuntilitem1ofstack=(orlengthofstack=0additem1ofstacktoqueuedelete1ofstackendifitem1ofstack=(thendelete1ofstackendendchangeiby1endrepeatuntillengthofstack=0additem1ofstacktoqueuedelete1ofstackendrepeatuntillengthofqueue=0Stackmachinesettokentoitem1ofqueuedelete1ofqueueifoperatorscontainstokentheniftoken=+theninsertitem2ofstack+item1ofstackat1ofstackendiftoken=-theninsertitem2ofstack-item1ofstackat1ofstackendiftoken=/theninsertitem2ofstack/item1ofstackat1ofstackendiftoken=*theninsertitem2ofstack*item1ofstackat1ofstackenddelete2ofstackdelete2ofstackelseinserttokenat1ofstackendendsetresulttoitem1ofstackTheanswerwillbestoredintheresultvariable

Explanation

The problem of evaluating an expression can be broken down into 3 steps:

  1. Tokenizing the expression (turning the input into a list of symbols and numbers)
  2. Converting the tokens to postfix format (where the operator goes after the 2 operands)
  3. Evaluating the postfix expression with a stack machine (calculating the answer)


Tokenizing the expression

The expression must first be converted into a list. Every number must have all its digits in the same list element.

This script will tokenize an expression:

setito1deletealloftokensrepeatlengthofexpressionsetlettertoletteriofexpressionsetlasttokentoitemlengthoftokensoftokensif123456.7890containslettertheniflasttoken/1=lasttokenorlasttoken=.thenreplaceitemlengthoftokensoftokenswithjoinlasttokenletterelseaddlettertotokensendelseif()+-/*containsletterthenaddlettertotokensendend


Converting the tokens to postfix format

Next the Shunting yard algorithm is used to convert the tokens from infix (A op B) to postfix (A B op). This is done because it's a lot less code to calculate a postfix expression than an infix one.

This script will run the shunting yard algorithm on the tokens list:

Шаблон:Note

deleteallofstackdeleteallofqueuesetito1repeatlengthoftokenssettokentoitemioftokensiftoken/1=tokenthenaddtokentoqueueendifoperatorscontainstokenthenrepeatuntilitem1ofstack=(orlengthofstack=0oritem#ofitem1ofstackinoperators<item#oftokeninoperatorsadditem1ofstacktoqueuedelete1ofstackendinserttokenat1ofstackendiftoken=(theninserttokenat1ofstackendiftoken=)thenrepeatuntilitem1ofstack=(orlengthofstack=0additem1ofstacktoqueuedelete1ofstackendifitem1ofstack=(thendelete1ofstackendendchangeiby1endrepeatuntillengthofstack=0additem1ofstacktoqueuedelete1ofstackend


Calculating the result with a stack machine

This script will calculate the result of the postfix expression:

repeatuntillengthofqueue=0settokentoitem1ofqueuedelete1ofqueueifoperatorscontainstokentheniftoken=+theninsertitem2ofstack+item1ofstackat1ofstackendiftoken=-theninsertitem2ofstack-item1ofstackat1ofstackendiftoken=/theninsertitem2ofstack/item1ofstackat1ofstackendiftoken=*theninsertitem2ofstack*item1ofstackat1ofstackenddelete2ofstackdelete2ofstackelseinserttokenat1ofstackendendsetresulttoitem1ofstack

Using the Custom Block

whenclickedevaluate5+5sayreturn

If it worked, your sprite should say 10.