g | x | w | all
Bytes Lang Time Link
363C gcc250527T032444Zceilingc
nanGo250531T044532Zuser1280
467Rust250521T020016Zceilingc
201Ruby250522T075107ZValue In
153Uiua240304T192036Zjan
209JavaScript Node.js240304T031642Ztsh
263JavaScript ES6240303T174617ZArnauld
116Charcoal240303T090238ZNeil
795JavaScript Node.js240302T015918Z2pichar
117K ngn/k240229T174254Zovs

C (gcc), 481 464 448 429 417 402 391 380 363 bytes

z=128;*strtok();atoi();*f(char*s){int a['2d']={},*b=a,*c,*k=a,i=0,m;char*p;for(;m=p=strtok(i++?0:s," ");)if(*p>47)*p>57?b[*p-z]=1:(*b=atoi(p),b+=z);else for(b-=m=z,c=b-z,*p>46?*c/=*b:*p%2?*c+=*b:(*c*=*b);--m;b[m]=0)if(*p-43)c[m]-=b[m]*(*p%2*2-1);else if(c[m]-b[m])return"*";for(p=s;k<b;k++,m%=z)p+=sprintf(p,"%c%2$d%3$s"+(m++?!*k*6:2),m,*k,(m<~-z)+" ");return s;}

Try it online!

Slightly less golfed.

*strtok(int*,int);atoi();
*f(char*s){
  int a['2d']={},i=0,j=0,k=0,m;
  for(char*p;p=strtok(i++?0:s," ");)          // split input string
    if(m=128,*p<48){                          // +, * or /
      j--;
      if(*p-43)                               // * or /
        for(*p-47?a[m*~-j]*=a[m*j]:(a[m*~-j]/=a[m*j]);--m;)
          a[128*~-j+m]+=a[128*j+m]*(*p-47?1:-1);
      else                                    // +
        if(a[~-j*m]+=a[j*m],bcmp(a+m*j+1,a+m*~-j+1,508))
          return"*";
      bzero(a+128*j,512);
    }else
      *p>57?a[m*~-j+*p]=1:(a[j++*m]=atoi(p)); // number or unit
  for(i=0;m=k<j;strcat(s+i++," "),k++)        // construct output
    for(i+=sprintf(s+i,"%d",a[k<<7]);m<128;m++)
      a[k*128+m]?i+=sprintf(s+i,"%c%d",m,a[k*128+m]):0;
  return s;
}

Go, 665 519 518 513 502 500 498 bytes

Saved (146+1+5+11+2+2)=167 bytes thanks to @ceilingcat

     

Golfed version. Attempt This Online!

func f(x[]string)string{a,i,z:=make([]int,25600),0,256;var u strings.Builder;for _,t:=range x{if"0">t{i-=z;if"+">t{a[i-z]*=a[i]}else if"/">t{a[i-z]+=a[i]}else{a[i-z]/=a[i]};for m:=1;m<z;m++{if"+"==t{if a[i-z+m]!=a[i+m]{return"*"}}else{a[i-z+m]+=a[i+m]*map[string]int{"*":1,"/":-1}[t]};a[i+m]=0}}else if"A">t{fmt.Sscan(t,&a[i]);i+=z}else{a[i-z+int(t[0])]+=1}};for t:=range i{if a[t]!=0{if t%z>0{u.WriteByte(byte(t))};u.WriteString(strconv.Itoa(a[t]))};if-^t%z<1{u.WriteByte(' ')}};return u.String()}

Less golfed version. Attempt This Online!

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func f(x []string) string {
	a := make([]int, 12800)
	var u strings.Builder
	i := 0
	
	for _, t := range x {
		if t < "0" { // +, * or /
			i -= 1
			if t == "+" { // + operator
				for m := 1; m < 128; m++ {
					if a[128*(i-1)+m] != a[128*i+m] {
						return "*"
					}
				}
				a[128*(i-1)] += a[128*i]
			} else {
				if t == "*" { // * operator
					a[128*(i-1)] *= a[128*i]
					for m := 1; m < 128; m++ {
						a[128*(i-1)+m] += a[128*i+m]
					}
				} else { // / operator
					a[128*(i-1)] /= a[128*i]
					for m := 1; m < 128; m++ {
						a[128*(i-1)+m] -= a[128*i+m]
					}
				}
			}
			for m := 1; m < 128; m++ {
				a[128*i+m] = 0
			}
		} else if t < "A" { // numbers
			val, _ := strconv.Atoi(t)
			a[128*i] = val
			i++
		} else { // units
			a[128*(i-1)+int(t[0])] += 1
		}
	}
	
	for t := 0; t < i; t++ {
		u.WriteString(strconv.Itoa(a[128*t]))
		for v := 1; v < 128; v++ {
			if a[128*t+v] != 0 {
				u.WriteByte(byte(v))
				u.WriteString(strconv.Itoa(a[128*t+v]))
			}
		}
		u.WriteByte(' ')
	}
	
	return u.String()
}

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	for scanner.Scan() {
		input := scanner.Text()
		tokens := strings.Fields(input)
		fmt.Println(f(tokens))
	}
}

Rust, 1559 1514 1493 1448 1347 1306 663 609 580 564 538 508 492 484 467 bytes

fn f(x:&[&str])->String{let(mut a,mut u,mut i,z)=(vec![0;25600],format!(""),0,256);for t in x{if&"0">t{i-=z;match t{&"+"=>a[i-z]+=a[i],&"/"=>a[i-z]/=a[i],_=>a[i-z]*=a[i]}for m in 1..z{if&"+"!=t{a[i-z+m]+=a[i+m]*if&"/">t{1}else{-1}}else if a[i-z+m]!=a[i+m]{return format!("*")}a[i+m]=0}}else if&"A">t{a[i]=t.parse().unwrap();i+=z}else{a[t.as_bytes()[0]as usize+i-z]+=1}}for t in 0..i{if a[t]!=0{if t%z>0{u.push(t as u8 as char)}u+=&a[t].to_string()}if!t%z<1{u+=" "}}u}

Try it online!

Slightly less golfed:

fn f(x:&[&str])->String{
  let mut a:[i32;12800]=[0;12800];
  let(mut u,mut i)=(String::new(),0);
  for t in x{
    if&"0">t{                            // +, * or /
      i-=1;
      if&"+"==t{                         // + operator
        for m in 1..128{
          if a[128*(i-1)+m]!=a[128*i+m]{
            return format!("*")
          }
        }
        a[128*(i-1)]+=a[128*i]
      }else{
        if&"*"==t{                       // * operator
          a[128*(i-1)]*=a[128*i];
          for m in 1..128{
            a[128*(i-1)+m]+=a[128*i+m]
          }
        }else{                           // / operator
          a[128*(i-1)]/=a[128*i];
          for m in 1..128{
            a[128*(i-1)+m]-=a[128*i+m]
          }
        }
      }
      for m in 1..128{
        a[128*i+m]=0
      }
    }else
      if&"A">t{                          // numbers
        a[128*i]=str::parse::<i32>(t).unwrap();
        i+=1
      }else{                             // units
        a[128*(i-1)+(t.as_bytes()[0]as usize)]+=1
      }
    }
  for t in 0..i{
    u.push_str(&a[128*t].to_string());
    for v in 1..128{
      if a[128*t+v]!=0{
        u.push(v as u8 as char);
        u.push_str(&a[128*t+v].to_string())
      }
    }
    u.push(' ')
  }
  u
}

Ruby, 201 bytes

Errors due to mismatched types when adding throw a NameError by calling the uninitialized variable X.

->i,*s{i.map{|o|o=~/[a-z]/?s[-1][1][o]=1:s<<(o=~/\d/?[o.to_i,{}]:(x,y=s.pop 2;a,b=x;c,d=y
[eval([a,c]*o),o==?+?b==d ?b:X: b&&d ?b.merge(d){o==?*?_2+_3: _2-_3}.reject{_2==0}:b||d]))}
s.map{[_1,*_2]*''}}

Attempt This Online! (prints * if it errors out)

Uiua, 204 192 178 153 characters

-12: remove error handling and output reversal and redundant spaces that the formatter always puts back in.
-14: use "uiuisms" page to golf character range, use content ◇ instead of unbox, and golf creation of the stack.
-25: Get less stingy with memory usage, etc.

P←⊙:⊙⊙°⊂∩°⊂°⊂◌
r←⇡27
a←⍜°⊂(@ ◌)+@`r
i←⊙(⟨⊂⊂⊓×+P|⊂⊂⊓+⟜(⍤"*"≍)P|◌|◌|◌|⊂⊂⊓÷-P|⟨⍜⊙°⊂+=a|⊂×=0r⋕⟩⍣(1◌⋕)0.⟩↧6/+-@*.):°□°⊂ 
(↘1/◇⊂♭≡(⨬(□""◌◌|□⊂⊙°⋕)≠0,a)◌⍥i⧻.:↯0r)

commented version with tests golfed version

P ← ⊙:⊙⊙°⊂∩°⊂°⊂ # pop 2 from small stack and separate number and units
r ← ⇡27
a ← ⍜°⊂(@ ◌)+@`r
i ← ⊙(
  ⨬(
    ⊂⊂⊓×+P◌        # times
  | ⊂⊂⊓+⟜(⍤"*"≍)P◌ # plus
  | ◌
  | ◌
  | ◌       # other characters
  | ⊂⊂⊓÷-P◌ # divided by
  | ⨬(
      ⍜⊙°⊂+=a # letter: add one to corresponding cell in top of small stack
    | ⊂×=0r⋕  # number: push unitless number to small stack
    )⍣(1◌⋕)0.
  )↧6/+-@*. # ---the difference from star, or 6 if it's a number or letter
):°□°⊂      # process one token from the input 
f ← (
  ◌⍥i⧻.:↯0r             # setup the label and small stack
  ≡(⨬(□""◌◌|□⊂⊙°⋕)≠0,a) # append unit to each number in the small stack
  ↘1/◇⊂♭                # final concatenation
)

Input is a boxed array ({}) of token strings, or there is an extra string parsing function in the formatted version link.

JavaScript (Node.js), 209 bytes

p=>p.map(n=>a.push(y=+n?[+n,...Buffer(36)]:n<0+a.pop()?a.pop().map((o,i)=>(m=y[i],i)?n<'+'?o+m:n<'/'?o-m?E:o:o-m:eval(o+n+m)):(y[parseInt(n,36)]=1,y)),a=[])&&a.map(x=>x.reduce((x,v,i)=>v?x+i.toString(36)+v:x))

Attempt This Online!

Input array of tokens, output array of values or throw error.

JavaScript (ES6), 263 bytes

s=>s.replace(/\S+/g,v=>v>{}?s[0][1]=[[v,1]]:s=[[(u=[])|v||([[y,q],[x,u],...s]=s,v+1|0?e|=u+''!=q:q.map(([U,e])=>(u.find(o=>o[0]==U)||u.push(o=[U,0])&&o)[1]+=v<"/"?e:-e),eval(x+v+y)),u.filter(o=>o[1]).sort()],...s],e=s=[])|e?"*":s.reverse().join` `.split`,`.join``

Try it online!

Charcoal, 123 116 bytes

F⪪S ¿Σι⊞υ⁺⟦Iι⟧Eβ⁰¿№βι§≔§υ±¹⊕⌕βι¹«≔⊟υζ≔⊟υη⊞υ∧∨⬤∧ζη∨¬λ⁼κ§ζλ⁻+ιE∧ζη⎇λ⁻κ×§ζλ⊖﹪℅ι³§⟦×κ§ζλ⁺κ§ζλ÷κ§ζλ⟧℅ι»Eυ⭆∨ι*⎇μ⎇λ⁺§β⊖μλωλ

Try it online! Link is to verbose version of code. Since the whole stack is output, I've effectively included several test cases in the link. Explanation:

F⪪S 

Split the input on spaces and loop over the resulting tokens.

¿Σι⊞υ⁺⟦Iι⟧Eβ⁰

If this token is a positive integer, then push its value with zero exponents for all letters.

¿№βι§≔§υ±¹⊕⌕βι¹

Otherwise, if this token is a letter, then set the exponent for that letter to 1 for the latest value.

«

Otherwise:

≔⊟υζ≔⊟υη

Retrieve the two arguments.

⊞υ∧∨⬤∧ζη∨¬λ⁼κ§ζλ⁻+ιE∧ζη⎇λ⁻κ×§ζλ⊖﹪℅ι³§⟦×κ§ζλ⁺κ§ζλ÷κ§ζλ⟧℅ι

If the arguments are compatible or the operations is not sum, calculate the product, sum and quotient of the two arguments, selecting according to the ordinal of the token. (In the case of the exponents, the ordinal modulo 3 is decremented and multiplied by the second exponent, and this is subtracted from the first exponent.)

»Eυ⭆∨ι*⎇μ⎇λ⁺§β⊖μλωλ

For each value on the stack, concatenate its value with any non-zero exponents, unless the value was invalid, in which case output a *.

JavaScript (Node.js), 797 795 bytes

Z=require('util');O=Object;N="length";A=u=>O.fromEntries([...u.matchAll(/([a-zA-Z])(-?\d+)/g)].map(_=> _.slice(1)));B=u=>{s="";e=O.entries(u);for(i=0;i<e[N];i++){s+=e[i][0]+e[i][1]}return s};D=T=>{S=[];U=[];p=/[+*\/]/;for(t of T){if(/\d+/.test(t[0])||/\d+/.test(t[1])&&(t[0]=="-"||t[0]=="+")){S.push(t)}else if(p.test(t)){let[r,l]=[S.pop(),S.pop()];[h,H]=[U.pop(),U.pop()];if(H){f=A(h);g=A(H);m=1;if(t=="+"){if(Z.isDeepStrictEqual(g,f)){n=B(g)}else{return'*'}}if(t=="/"){m=-1}L=O.keys(g);P=O.keys(f);z={};for(i=0;i<L[N];i++){k=L[i];if(k in f){y=+g[k]+m*+f[k];y!=0?(z[k]=y):0}else{z[k]=+g[k]}}for(i=0;i<P[N];i++){k=P[i];if(!(k in z||k in g)){z[k]=m*+f[k]}}n=B(z);n!=""?U.push(n):0}S.push(""+eval(l+t+r))}else{if(t[N] > 1){U.push(t)}else{U.push(t+1)}}}return S.map((E,I)=> E+(U[I]||"")).join(" ")}

Try it online! Input is as an array of token strings passed to D. Output is to STDOUT. There's probably a shorter way, but this is what I've got (and JS is not a golfing language).

K (ngn/k), 134 124 117 bytes

{,//$x,(!y),'.y}.'|(){(,$[43=*y-*|&/=/h;E;1=C;**x;^[_%;.y].|*'h],(&~b)_b:(y!C;*|(1-3!*y)/h:C#x)2=C),(C:3!"0a"'*y)_x}/

Try it online! Input and output as list of strings, t converts between that and space separated format.