Zum Verzeichnisinhalt
Zum Aufgabenblatt
(SHIFT + Linke Maustaste)
@=~
~p maximum_input_line_length = infinity
~A~<Structuring~>
~B~<Specification~>
The structure of the example language is specified by the following
concrete grammar productions.
A program is a block that consists of possibly empty sequences
of declarations and statements.
~$~<Program~>~{
Prog ::= Block .
Block ::= '{' Decl* Stmt* '}' .
~}
A declaration defines one or more variables of type int.
Each declaration is terminated by a ';'.
The symbol ~{VarDecl~} distinguishes this defining occurrence
of ~{Ident~} from other occurrences.
Several identifiers are separated by ','.
~$~<Declarations~>~{
Decl ::= 'int' VarDecls ';' .
VarDecls::= VarDecl // ',' .
VarDecl ::= Ident .
~}
There are several forms of statements: assignments, conditionals,
~{switch~} statements, ~{break~} statements, ~{for~} loops,
blocks, and expression statements.
Statements, except blocks and ~{switch~} statements
are terminated by ';'.
~$~<Statements~>~{
Stmt ::= Block
/ Expr ';'
/ 'break' ';'
/ Assign ';'
/ ForStmt .
~}
An assignment has the usual notation.
The ~{Assign~} symbol is introduced, because ~{for~} loops contain
assignments without terminating ';'.
~$~<Assignments~>~{
Assign ::= VarUse '=' Expr .
VarUse ::= Ident .
~}
~{for~} statements consist of the initial assignment, the iteration
condition, the assignment executed after each iteration, and the
iterated statement.
~$~<For loop~>~{
ForStmt ::= 'for' '(' Assign ';' Expr ';' Assign ')' Stmt .
~}
The ~{else~} branch of an ~{if~} statement is optional.
The dangling else ambiguity is resolved such that an ~{else~}
branch is bound to the innermost ~{if~} statement.
The ~{$'else'~} modification instructs
the parser generator not to reduce that production if an ~{else~}
token follows.
~$~<If statement~>~{
Stmt ::= 'if' '(' Expr ')' Stmt $'else' .
Stmt ::= 'if' '(' Expr ')' Stmt 'else' Stmt .
~}
Switch statements have the same structure as in C.
~$~<Switch statement~>~{
Stmt ::= SwStmt .
SwStmt ::= 'switch' '(' Expr ')' '{' Case* '}' .
Case ::= CaseLab Stmt* .
CaseLab ::= 'case' CaseLit ':' .
CaseLab ::= 'default' ':' .
CaseLit ::= Number .
~}
The following expression syntax specifies precedence and
associativity of operators: ~{MulOpr~} have highest precedence,
~{CmpOpr~} have lowest precedence. ~{AddOpr~} and ~{MulOpr~}
are left-associative, and ~{CmpOpr~} are not associative.
~$~<Expressions~>~{
Expr ::= Sum CmpOpr Sum / Sum .
Sum ::= Sum AddOpr Fact / Fact .
Fact ::= Fact MulOpr Operand / Operand .
CmpOpr ::= '<' / '>' / '==' / '!=' / '<=' / '>=' .
AddOpr ::= '+' / '-' .
MulOpr ::= '*' / '/' .
Operand ::= '(' Expr ')' .
~}
The precedence and associativity rules are only relevant for
the construction of the tree. The then constructed tree need not
distinguish between ~{Expr~}, ~{Sum~}, ~{Fact~}, and
~{Operand~}. They are all represented by an Expr node.
Similarly all operators are represented
by an ~{Opr~} node in the tree:
~$~<Equivalent nonterminals~>~{
Expr ::= Sum Fact Operand .
Opr ::= CmpOpr AddOpr MulOpr .
~}
Operands are integral numbers, identifiers that denote access
of a variable value, or calls of predefined functions.
The latter may have an arbitrary number of arguments.
~$~<Operands~>~{
Operand ::= Number .
Operand ::= VarUse .
Operand ::= Ident '(' Params ')' .
Params ::= .
Params ::= Expr // ',' .
~}
The notation for numbers, identifiers, and comments are specified
as in C using canned token specifications:
~$~<Tokens~>~{
Number: C_INTEGER
Ident: C_IDENTIFIER
C_COMMENT
~}
~B~<Output of files~>
~O~<tree.con~>~{
~<Program~>
~<Declarations~>
~<Statements~>
~<Assignments~>
~<For loop~>
~<If statement~>
~<Switch statement~>
~<Expressions~>
~<Operands~>
~}
~O~<tree.sym~>~{
~<Equivalent nonterminals~>
~}
~O~<tree.gla~>~{
~<Tokens~>
~}