Revisions:
This document outlines the processing required to perform a full semantic analysis for a Source language program. The annotated grammar below adds references to additional semantic analysis operators in blue that refer to specific semantic checks that should be performed.
program: | SCtopBegin bareScope SCtopEnd | # program top-level |
bareScope: | declarations SCdecls | # only declarations |
| declarations SCdecls statements | # both declarations and statements | |
| statements | # only statements | |
scope: |
SCminorBegin { bareScope } SCminorEnd
|
# scope enclosed with braces |
| { }
|
# empty scope | |
statements: |
variable = expression CTassign
|
# assignment |
| if expression CTbool scope
|
# conditional statement | |
| if expression CTbool scope elseIfArms
|
||
| if expression CTbool scope else scope
|
||
| if expression CTbool scope elseIfArms else scope
|
||
| while expression CTbool scope
|
# loop while expression is true | |
| repeat scope until expression CTbool
|
# loop until expression is true | |
| break STbreak
|
# exit out of enclosing loop | |
| break integer STbreak STloopDepth
|
# exit out of multiple enclosing loops | |
| return ( expression ) STreturnFunc CTreturn
|
# return from a function | |
| return STreturnProc
|
# return from a procedure | |
| print outputs
|
# print to standard output | |
| input inputs
|
# input from standard input | |
| procedureName ( ) RzeroArgs
|
# procedure call (no arguments) | |
| procedureName ( arguments ) RmatchArgs
|
# procedure call (with arguments) | |
| scope | # nested scope | |
| statements statements | # sequence of statements | |
elseIfArms: |
else if expression CTbool scope
|
# else-if arm |
| elseIfArms elseIfArms | # sequence of else-if arms | |
declarations: |
var variableNames compoundType Dvariables
|
# declare variables |
| func SCprocBegin procedureName ( ) Dproc scope SCprocEnd DlinkScope
|
||
| func SCprocBegin procedureName ( parameters ) Dproc scope SCprocEnd DlinkScope
|
||
| func SCfuncBegin functionName ( ) scalarType Dfunc scope SCfuncEnd SThasReturn DlinkScope
|
||
| func SCfuncBegin functionName ( parameters ) scalarType Dfunc scope SCfuncEnd SThasReturn DlinkScope
|
||
| declarations declarations | # sequence of declarations | |
variableNames: | variableName | |
| variableNames , variableNames
|
# comma separated sequence of variable names | |
scalarType: |
integer Tint
|
# integer type |
| boolean Tbool
|
# Boolean type | |
compoundType: | scalarType | |
| [ bound ] scalarType
|
# 1-dimensional array type | |
| [ bound ] [ bound ] scalarType
|
# 2-dimensional array type | |
bound: | integer | # array of length integer |
parameters: | parameterNames scalarType Dparams | # declare one or more formal parameters |
| parameters , parameters
|
# sequence of formal parameters | |
parameterNames: | parameterName | |
| parameterNames , parameterNames
|
# comma separated sequence of parameter names | |
arguments: | expression CTargument | |
| arguments , arguments
|
# comma separated sequence of arguments | |
outputs: | expression | # integer or Boolean expression value to be printed |
| text | # string constant to be printed | |
| newline
|
# print newline | |
| outputs , outputs
|
# sequence of output arguments | |
inputs: | variable CTint | # input to this integer variable |
| inputs , inputs
|
# input sequence | |
variable: | variableName Tvar | # reference to scalar variable |
| arrayName [ expression CTint ] Tarr
|
# reference to 1-dimensional array element | |
| arrayName [ expression CTint ] [ expression CTint ] Tarr
|
# reference to 2-dimensional array element | |
expression: | integer Tint | # literal integer constant |
| - expression CTint Tint
|
# unary minus | |
| expression CTint + expression CTint Tint
|
# addition | |
| expression CTint - expression CTint Tint
|
# subtraction | |
| expression CTint * expression CTint Tint
|
# multiplication | |
| expression CTint / expression CTint Tint
|
# integer division | |
| true Tbool
|
# Boolean constant true | |
| false Tbool
|
# Boolean constant false | |
| not expression CTbool Tbool
|
# Boolean not | |
| expression CTbool and expression CTbool Tbool
|
# Conditional Boolean and | |
| expression CTbool or expression CTbool Tbool
|
# Conditional Boolean or | |
| expression = expression CTmatch Tbool
|
# equality comparison | |
| expression != expression CTmatch Tbool
|
# inequality comparison | |
| expression CTint < expression CTint Tbool
|
# less-than comparison | |
| expression CTint <= expression CTint Tbool
|
# less-than-or-equal comparison | |
| expression CTint > expression CTint Tbool
|
# greater-than comparison | |
| expression CTint >= expression CTint Tbool
|
# greater-than-or-equal comparison | |
| ( expression ) Texpr
|
||
| ( expression if expression CTbool else expression ) CTvalues Tcond
|
# Python-style ternary conditional expression | |
| variable | # reference to local variable | |
| functionName ( ) RzeroArgs Treturn
|
# function call (no arguments) | |
| functionName ( arguments ) RmatchArgs Treturn
|
# function call (with arguments) | |
| parameterName Tparam | # reference to a formal parameter | |
variableName: | identifier CTscalar | |
arrayName: | identifier CTarray | |
functionName: | identifier RfuncId | |
parameterName: | identifier CTparam | |
procedureName: | identifier RprocId |
break
statement is directly inside of a loop.return
(
expression )
statement is directly inside of a function.return
statement is directly inside of a procedure.return
(
expression )
statement.if
, while
, and repeat
...until
statements must be Boolean valued.return
(
expression )
statement must match the return type of the enclosing function declaration.input
statement must be something that can be assigned into, and must be integer valued.return
can only appear within a directly enclosing procedure.return
with expression can only appear within a directly enclosing function.break
can only appear within a loop.break
must break out of at least 1 loop, and cannot break out of more enclosing loops that are present within the enclosing major scope.The definitions of STbreak, STloopDepth, STreturnFunc and STreturnProc refer to being directly inside of, or within a directly enclosing loop, function or procedure. This refers to statements that would otherwise be legal, except for the presence of the loop or procedure/function between the statement and the intended enclosing context. These restrictions should reset at procedure and function boundaries. For example:
func F() integer { func P() { return (488) // illegal, violates STreturnFunc } }
func Q() { func G() integer { return // illegal, violates STreturnProc } }
while true { func R() { break // illegal, violates STbreak } func H() integer { break 1 // still illegal } }
while true { func S() { while true { break 2 // illegal, violates STloopDepth } } }
func J() boolean { while true { func T() { repeat { if false { break // legal, within a loop } else { return // legal, also within a procedure } } until true } } }
This document is a companion to the Source language specification, and should not be seen to change that specification in any way. Nor should you, through your implementation of a semantic analyzer, change the syntax of the language in any way. If you find any point on which these two documents disagree, please report this to the instructor and consider this document to be in error.