Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
137 views

Semantics

This document discusses different approaches to defining the semantics of programming languages, including static semantics, dynamic semantics, operational semantics, axiomatic semantics, and denotational semantics. It provides examples and explanations of each approach. Specifically: - Static semantics can be defined using attribute grammars, which carry semantic information through a parse tree and allow static semantic checks. Attribute grammars assign attributes, functions, and predicates to grammar rules. - Operational semantics defines meaning by describing state transformations of an abstract machine when executing program statements. - Axiomatic semantics defines preconditions and postconditions for statements using logical assertions and inference rules. It allows proving properties about programs. - Denotational semantics maps language elements to

Uploaded by

Guilherme Lima
Copyright
© © All Rights Reserved
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
137 views

Semantics

This document discusses different approaches to defining the semantics of programming languages, including static semantics, dynamic semantics, operational semantics, axiomatic semantics, and denotational semantics. It provides examples and explanations of each approach. Specifically: - Static semantics can be defined using attribute grammars, which carry semantic information through a parse tree and allow static semantic checks. Attribute grammars assign attributes, functions, and predicates to grammar rules. - Operational semantics defines meaning by describing state transformations of an abstract machine when executing program statements. - Axiomatic semantics defines preconditions and postconditions for statements using logical assertions and inference rules. It allows proving properties about programs. - Denotational semantics maps language elements to

Uploaded by

Guilherme Lima
Copyright
© © All Rights Reserved
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
You are on page 1/ 28

Semantics

Static semantics

attribute grammars

examples
computing attribute values
status

Dynamic semantics

operational semantics
axiomatic semantics
examples
loop invariants
evaluation

denotational semantics
examples
evaluation

(3.1)

Static Semantics

(3.2)

Used to define things about PLs that are


hard or impossible to define with BNF
hard: type compatibility
impossible: declare before use

Can be determined at compile time


hence the term static

Often specified using natural language


descriptions
imprecise

Better approach is to use attribute


grammars
Knuth (1968)

Attribute Grammars

(3.3)

Carry some semantic information along


through parse tree
Useful for
static semantic specification
static semantic checking in compilers

An attribute grammar is a CFG G = (S, N,


T, P) with the additions

for each grammar symbol x there is a set


A(x) of attribute values
each production rule has a set of functions
that define certain attributes of the nonterminals in the rule
each production rule has a (possibly
empty) set of predicates to check for
attribute consistency
valid derivations have predicates true for
each node

Attribute Grammars (continued)

(3.4)

Synthesized attributes
are determined from nodes of children in
parse tree
if X0 -> X1 ... Xn is a rule, then S(X0) =
f(A(X1), ..., A(Xn))

pass semantic information up the tree

Inherited attributes
are determined from parent and siblings
I(Xj) = f(A(X0), ..., A(Xn))
often, just X0 ... Xj-1
siblings to left in parse tree

pass semantic information down the tree

Attribute Grammars (continued)


Intrinsic attributes
synthesized attributes of leaves of
parse tree
determined from outside tree
e.g., symbol table

(3.5)

Attribute Grammars (continued)

(3.6)

Example: expressions of the form id + id


- id's can be either int_type or real_type
- types of the two id's must be the same
- type of the expression must match its
expected type
BNF: <expr> -> <var> + <var>
<var> -> id
Attributes:
actual_type - synthesized for <var> and
<expr>
expected_type - inherited for <expr>
env - inherited for <expr> and <var>

Attribute Grammars (continued)

(3.7)

Think of attributes as variables in the parse


tree, whose values are calculated at compile
time
conceptually, after parse tree is built

Example attributes
actual_type

intrinsic for variables


determined from types of child nodes for <expr>

expected_type
for <expr>, determined by type of variable on
LHS of assignment statement, for example

env
pointer to correct symbol table environment, to
be sure semantic information used is correct set
think of different variable scopes

Attribute Grammars (continued)

(3.8)

Attribute Grammar:
1. syntax rule: <expr> -> <var>[1] + <var>[2]
semantic rules:
<var>[1].env <- <expr>.env
<var>[2].env <- <expr>.env
<expr>.actual_type <<var>[1].actual_type
predicate:
<var>[1].actual_type =
var>[2].actual_type
<expr>.expected_type = <expr>.actual_type
2. syntax rule: <var> -> id
semantic rule:
<var>.actual_type <- lookup

Computing Attribute Values

(3.9)

If all attributes were inherited, could


decorate the tree top-down
If all attributes were synthesized,
could decorate the tree bottom-up
Usually, both kinds are used
use both top-down and bottom-up
approaches
actual determination of order can be
complicated, requiring calculations of
dependency graphs

One order that works for this simple


grammar is on the next slide

Computing Attribute Values (continued)

(3.10)

1. <expr>.env <- inherited from parent


<expr>.expected_type <- inherited from
parent
2. <var>[1].env <- <expr>.env
<var>[2].env <- <expr>.env
3. <var>[1].actual_type <lookup(A,<var>[1].env)
<var>[2].actual_type <- lookup
(B,<var>[2].env)
<var>[1].actual_type =? <var>[2].actual_type
4. <expr>.actual_type <- <var>[1].actual_type
<expr>.actual_type =? <expr>.expected_type

Status of Attribute Grammars

(3.11)

Well-defined, well-understood
formalism
used for several practical compilers

Grammars for real languages can


become very large and cumbersome
and take significant amounts of
computing time to evaluate

Very valuable in a less formal way for


actual compiler construction

Dynamic Semantics

(3.12)

Describe the meaning of PL constructs


No single widely accepted way of
defining
Three approaches used
operational semantics
axiomatic semantics
denotational semantics

All are still in research stage, rather


than practical use
most real compilers use ad-hoc
methods

Operational Semantics

(3.13)

Describe meaning of a program by


executing its statements on a machine
actual or simulated
change of state of machine (values in
memory, registers, etc.) defines
meaning

Could use actual hardware machine


too expensive

Could use a software interpreter


too complicated, because of underlying
machine complexity
not transportable

Operational Semantics (continued)

(3.14)

Most common approach is to use


simulator for simple, idealized (abstract)
machine
build a translator (source code to machine
code of simulated machine)
build a simulator
describe state transformations of
simulated machine for each PL construct

Evaluation

good if used informally


can have circular reasoning, since PL is
being defined in terms of another PL

extremely complex if used formally


VDL description of semantics of PL/I was
several hundred pages long

Axiomatic Semantics

(3.15)

Define meaning of PL construct by effect


on logical assertions about constraints on
program variables
based on predicate calculus
approach comes from program verification

Precondition is an assertion before a PL


statement
states relationships and constraints among
variables before statement is executed

Postcondition is an assertion following a


statement
{P} statement {Q}

Axiomatic Semantics (continued)


Weakest precondition is least
restrictive precondition that will
guarantee postcondition
a := b + 1 {a > 1}
possible precondition: {b > 10}
weakest precondition: {b > 0}

(3.16)

Axiomatic Semantics (continued)

(3.17)

Axiom is a logical statement assumed


to be true
Inference rule is a method of inferring
the truth of one assertion based on
other true assertions
S1, S2, ...,
basic form for inference rule is
Sn
if S1, ..., Sn are true, S is true
S

Axiomatic Semantics (continued)

(3.18)

Then to prove a program


postcondition for program is desired
result
work back through the program
determining preconditions
which are postconditions for preceding
statement

if precondition on first statement is same


as program specification, program is
correct

To define semantics for a PL


define axiom or inference rule for each
statement type in the language

Axiomatic Semantics Examples

(3.19)

An axiom for assignment statements:


{Qx->E} x := E {Q}
Qx->E means evaluate Q with E substituted for X

The Rule of Consequence:


{P} S {Q}, P' => P, Q => Q'
------------------------------------{P'} S {Q'}

(3.20)

Axiomatic Semantics Examples (continued)


An inference rule for sequences
- For a sequence:
{P1} S1 {P2}
{P2} S2 {P3}
the inference rule is:

{P1} S1 {P2}, {P2} S2 {P3}


------------------------------------{P1} S1; S2 {P3}

(3.21)

Axiomatic Semantic Examples (continued)

An inference rule for logical pretest loops


For the loop construct:
{P} while B do S end {Q}
the inference rule is:
(I and B) S {I}
-----------------------------------------{I} while B do S {I and (not B)}
where I is the loop invariant.

Loop Invariant Characteristics

(3.22)

The loop invariant I must meet the


following conditions:
P => I
the loop invariant must be true initially

{I} B {I}
evaluation of the Boolean must not
change the validity of I

{I and B} S {I}
I is not changed by executing the body of
the loop

(I and (notB)) => Q


if I is true and B is false, Q is implied

The loop terminates


this can be difficult to prove

Axiomatic Semantics Evaluation

(3.23)

Developing axioms or inference rules


for all statements in a PL is difficult
Hoare and Wirth failed for function side
effects and goto statements in Pascal
limiting a language to those statements
that can have such rules written is too
restrictive

Good tool for research in program


correctness and reasoning about
programs
Not practically useful (yet) for language
designers and compiler writers

Denotational Semantics

(3.24)

Define meaning by mapping PL elements


onto mathematical objects whose
behavior is rigorously defined
based on recursive function theory
most abstract of the dynamic semantics
approaches

To build a denotational specification for


a language:
define a mathematical object for each
language entity
define a function that maps instances of
the language entities onto instances of
the corresponding mathematical objects

Denotational Semantics (continued)

(3.25)

The meaning of language constructs are


defined by only the values of the
program's variables
in operational semantics the state changes
are defined by coded algorithms
in denotational semantics, they are defined
by rigorous mathematical functions

The state of a program is the values of all


its current variables
Assume VARMAP is a function that, when
given a variable name and a state, returns
the current value of the variable
VARMAP(ij, s) = vj
state s)

(the value of ij in

Denotational Semantics (continued)

(3.26)

Consider some examples


Expressions
Me(E, s):

if VARMAP(i, s) = undef for some i in E


then error
else E, where E is the result of
evaluating E after setting each
variable i in E to VARMAP(i, s)

Assignment Statements
Ma(x:=E, s): if Me(E, s) = error
then error
else s = {<i1,v1>,...,<in,vn>},
where for j = 1, 2, ..., n,
vj= VARMAP(ij, s) if ij <> x
= Me(E, s) if ij = x

Denotational Semantics (continued)

(3.27)

Logical Pretest Loops


Ml(while B do L, s) : if Mb(B, s) = undef
then error
else if Mb(B, s) = false
then s
else if Msl(L, s) = error
then error
else Ml(while B do L,
Msl(L, s))

The meaning of the loop is the value of the program variables


after the
statements in the loop have been executed the prescribed
number of
times, assuming there have been no errors
- if the Boolean B is true, the meaning of the loop (state) is
the
meaning of the loop executed in the state caused by
executing

Denotational Semantics Evaluation

(3.28)

Can be used to prove the correctness of


programs
Provides a rigorous way to think about
programs
Can be an aid to language design
complex descriptions imply complex
language features

Has been used in compiler generation


systems
but not with practical effect

Not useful as descriptive mechanism for


language users

You might also like