Vanlig operatornotation
I programmeringsspråk är vetenskapliga miniräknare och liknande vanliga operatornotation eller operatorgrammatik ett sätt att definiera och analysera matematiska och andra formella uttryck . I denna modell är en linjär sekvens av tokens uppdelad i två klasser: operatorer och operander.
Operander är objekt som operatörerna opererar på. Dessa inkluderar bokstavliga tal och andra konstanter samt identifierare (namn) som kan representera allt från enkla skalära variabler till komplexa aggregerade strukturer och objekt, beroende på språkets komplexitet och förmåga samt användningskontext. En speciell typ av operand är parentesgruppen. Ett uttryck inom parentes utvärderas vanligtvis rekursivt för att behandlas som en enda operand på nästa utvärderingsnivå.
Varje operatör ges en position, företräde och en associativitet. Operatörens prioritet är ett tal (från högt till lågt eller vice versa) som definierar vilken operatör som tar en operand som är omgiven av två operatorer med olika prioritet (eller prioritet). Multiplikation har normalt högre företräde än addition, till exempel, så 3+4×5 = 3+(4×5) ≠ (3+4)×5.
När det gäller operatörsposition kan en operatör vara prefix, postfix eller infix. En prefixoperator går omedelbart före sin operand, som i −x. En postfix-operator efterträder omedelbart sin operand, som i x! till exempel. En infixoperator är placerad mellan en vänster och en höger operand, som i x+y. Vissa språk, framför allt C-syntaxfamiljen, sträcker ut denna konventionella terminologi och talar också om ternära infixoperatorer (a?b:c). Teoretiskt skulle det till och med vara möjligt (men inte nödvändigtvis praktiskt) att definiera parentes som en unär bifix-operation.
Operatörsassociativitet
Operatorassociativitet avgör vad som händer när en operand omges av operatorer med samma prioritet, som i 1-2-3: En operator kan vara vänsterassociativ , högerassociativ eller icke-associativ . Vänsterassociativa operatorer tillämpas på operander i vänster-till-höger-ordning medan högerassociativa operatorer är tvärtom. De grundläggande aritmetiska operatorerna är normalt alla vänsterassociativa, vilket betyder att 1-2-3 = (1-2)-3 ≠ 1-(2-3), till exempel. Detta gäller inte för högre operatörer. Till exempel exponentiering normalt högerassociativ i matematik, men implementeras som vänsterassociativ i vissa datorprogram som Excel. I programmeringsspråk där tilldelning implementeras som en operatör är den operatören ofta högerassociativ. Om så är fallet, skulle ett påstående som a := b := c vara ekvivalent med a := (b := c) , vilket innebär att värdet på c kopieras till b som sedan kopieras till a. En operatör som är icke-associativ kan inte konkurrera om operander med operatörer med samma prioritet. I Prolog till exempel är infixoperatorn :- icke-associativ, så konstruktioner som a :- b :- c är syntaxfel. Unära prefixoperatorer som − (negation) eller sin (trigonometrisk funktion) är vanligtvis associativa prefixoperatorer. När mer än en associativ prefix eller postfix-operator med lika prioritet föregår eller efterföljer en operand, går de operatorer som är närmast operanden först. Så −sin x = −(sin x), och sin -x = sin(-x).
Matematiskt orienterade språk (som på vetenskapliga miniräknare ) tillåter ibland implicit multiplikation med högre prioritet än prefixoperatorer (som sin), så att sin 2x+1 = (sin(2x))+1, till exempel. [ citat behövs ]
Prefixoperatorer (och postfix) har dock inte nödvändigtvis högre prioritet än alla infixoperatorer. Vissa (hypotetiska) programmeringsspråk kan mycket väl ha en operator som kallas sin med en prioritet lägre än × men högre än + till exempel. I ett sådant språk skulle sin 2·x+1 = sin(2·x)+1 vara sant, istället för (sin 2)·x+1, som normalt skulle vara fallet.
Reglerna för uttrycksutvärdering är vanligtvis trefaldiga:
- Behandla alla underuttryck inom parentes som en enda rekursivt utvärderad operand (det kan dock finnas olika typer av parenteser med olika semantik).
- Bind operander till operatorer med högre prioritet före de med lägre prioritet.
- För lika prioritet, bind operander till operatorer i enlighet med operatorernas associativitet.
Några fler exempel:
- 1-2+3/4*5+6+7 = (((1-2)+((3/4)*5))+6)+7 4
- + -x + 3 = (4 + (-x) )) + 3
Generaliseringar av Common Operator Notation
Användningen av operatörsprioritetsklasser och associativiteter är bara ett sätt. Det är dock inte det mest generella sättet: denna modell kan inte ge en operatör större företräde när den konkurrerar med '−' än den kan när den konkurrerar med '+', samtidigt som den fortfarande ger '+' och '−' ekvivalenta prioriteringar och associativiteter. En generaliserad version av denna modell (där varje operatör kan ges oberoende vänster- och högerprecedens) finns på [1] .