Skip to content

Attributed grammar

norman465 edited this page Nov 16, 2014 · 53 revisions

Attributierte Grammatik für das Bauen des AST

Program -> epislon | class IDENT { ClassMember'* } Program1

Sammeln der Declarations:

  • ClassMember_0.decls_in = {}
  • ClassMember'_i.decls_in += ClassMember''_i-1.decls_out

Das letzte Member n enthält alle Deklarationen

Weiterreichen der Klassen

  • Program1.classes_in = new ClassDeclaration(ClassMember'_n.decls_out)

Die letzte Klasse n enthält alle Klassen

  • Program.node = new Program(Program_1.classes_out)

ClassMember' -> public ClassMember''

  • ClassMember''.decls_in = ClassMember'.decls_in
  • ClassMember'.decls_out = ClassMember''.decls_out

ClassMember'' -> MainMethod'

  • MainMethod'.decls_in = ClassMember''.decls_in
  • ClassMember''.decls_out = MainMethod'.decls_out

ClassMember'' -> Member

  • Member.decls_in = Classmember''.decls_in
  • ClassMember''.decls_out = Member.decls_out

MainMethod' -> static void IDENT ( String [ ] IDENT ) Block

  • MainMethod'.decls_out = MainMethod'.decls_in + new MethodDeclaration(void, new Parameters(), Block.stmts)

Member -> Type IDENT Member'

  • Member'.decls_in = Member.decls_in
  • Member.decls_out = Member'.decls_out
  • Member'.type = Type.node
  • Member'.name = IDENT.lexval

Member' -> ;

  • Member'.decls_out = Member'.decls_in + new FieldDeclaration(Member'.type, Member'.name)

Member' -> ( Parameters? ) Block

  • Member'.decls_out = Member'.decls_in + new MethodDeclaration(Member'.type, member'.name, Parameters.params_out, Block.smts)

Parameters -> Parameter (, Parameters1)?

  • Parameters1.params_in = Parameters.params_in + Parameter.node
  • Parameters_out = Parameter.in + Parameter.node

Parameter -> Type IDENT

  • Parameter.node = new ParameterDefinition(Type.node, IDENT.lexval)

Type -> Basictype ([])*

  • Type.node = new BasicType(BasicType.type, arrayDepth)

BasicType -> int | boolean | void | IDENT

  • BasicType.type = int.lexval
  • Equivalent for boolean, void and IDENT.

Statement -> Block | EmptyStatement | IfStatement | ExpressionStatement | WhileStatement | ReturnStatement

  • Statement.stmts = Block.stmts
  • Equivalent for all other.

Block -> { BlockStatement* }

  • BlockStatement_i.smts = BlockStatement_i.smts + BlockStatement_i+1.stmts
  • Block.node = new Block(BlockStatement_n_stmts)

BlockStatement -> Block | EmptyStatement | IfStatement | ExpressionStatement | WhileStatement | ReturnStatement | LocalVariableDeclarationStatement

  • BlockStatement.stmts_out = BlockStatement.stmts_in + Block.node
  • BlockStatement.stmts_out = BlockStatement.stmts_in + EmptyStatement.node
  • Equivalent for all others.

LocalVariableDeclarationStatement -> Type IDENT (= Expression)? ;

  • LocalVariableDeclarationStatement.node = new LocalVariableDeclarationStatement(Type.node, IDENT.lexval, Expression.node)

EmptyStatement -> ;

  • EmptyStatement.node = {}

WhileStatement-> while ( Expression ) Statement

  • WhileStatement.node = new WhileStatement(Expression.node, Statement.node)

IfStatement -> if ( Expression ) Statement (else Statement1)?

  • IfStatement.node = new IfStatement(Expression.node, Statement.node, Statement1.node)

ExpressionStatement -> Expression ;

  • ExpressionStatement.node = Expression.node

ReturnStatement -> return Expression? ;

  • ReturnStatement.node = new ReturnStatement(Expression.node)

UnaryExpression

UnaryExpression -> PostfixExpression | (! | -) UnaryExpression1

UnaryExpression -> ! UnaryExpression1

  • UnaryExpression.node = new LogicalNotExpression(UnaryExpression1.node) UnaryExpression -> - UnaryExpression1
  • UnaryExpression.node = new NegateExpression(UnaryExpression1.node) UnaryExpression -> PostfixExpression
  • UnaryExpression.node = PostfixExpression.node

PostfixExpression -> PrimaryExpression (PostfixOp)*

  • PostfixExpression.node = PostfixOp.node
  • PostfixOp.in = PrimaryExpression.node
  • if no PostfixOp
  • PostfixExpression.node = PrimaryExpression.node

PostfixOp -> MethodInvocationFieldAccess | ArrayAccess

PostfixOp -> MethodInvocationFieldAccess

  • PostfixOp.node = MethodInvocationFieldAccess.node
  • MethodInvocationFieldAccess.in = PostfixOp.in PostfixOp -> ArrayAccess
  • PostfixOp.node = ArrayAccess.node
  • ArrayAccess.in = PostfixOp.in

MethodInvocationFieldAccess -> . IDENT MethodInvocationFieldAccess'

  • MethodInvocationFieldAccess.node = MethodInvocationFieldAccess'.node
  • MethodInvocationFieldAccess'.in = MethodInvocationFieldAccess.in
  • MethodInvocationFieldAccess'.ident = IDENT.lexval

MethodInvocationFieldAccess' -> ( Arguments ) | epsilon

MethodInvocationFieldAccess' -> ( Arguments )

  • MethodInvocationFieldAccess'.node = new MethodInvocationExpression(MethodInvocationFieldAccess'.in, MethodInvocationFieldAccess'.ident, Arguments.node) MethodInvocationFieldAccess' -> epsilon
  • MethodInvocationFieldAccess'.node = new VariableAccessExpression(MethodInvocationFieldAccess'.in, MethodInvocationFieldAccess'.ident)

ArrayAccess -> [ Expression ]

  • ArrayAccess.node = new ArrayAccessExpression(ArrayAccess.expr, Expression.node)

Arguments -> (Expression (, Expression)*)?

  • `Arguments.node = Arguments.node + Expression_i.node`` for all i

PrimaryExpression -> null | false | true | INTEGER_LITERAL | IDENT PrimaryIdent | this | ( Expression ) | new NewExpression

`PrimaryExpression -> null

  • PrimaryExpression.node = new NullExpression()

`PrimaryExpression -> this

  • PrimaryExpression.node = new ThisExpression()

PrimaryExpression -> false | true

  • PrimaryExpression.node = new BooleanConstantExpression(booleanvalue)

`PrimaryExpression -> INTEGER_LITERAL

  • PrimaryExpression.node = new IntegerConstantExpression(intvalue)

PrimaryExpression -> ( Expression )

  • PrimaryExpression.node = Expression.node

PrimaryExpression -> IDENT PrimaryIdent

  • PrimaryExpression.node = PrimaryIdent.node
  • PrimaryIdent.ident = IDENT.lexvalue

PrimaryExpression -> new NewExpression

  • PrimaryExpression.node = NewExpression.node

PrimaryIdent -> ( Arguments ) | epsilon

PrimaryIdent -> ( Arguments )

  • PrimaryIdent.node = new VariableAccessExpression(null, PrimaryIdent.ident) PrimaryIdent -> epsilon
  • PrimaryIdent.node = new MethodInvocationExpression(null, PrimaryIdent.ident, Arguments.node)

NewExpression -> IDENT NewIdentExpression | boolean NewArrayExpression | int NewArrayExpression | void NewArrayExpression

NewExpression -> IDENT NewIdentExpression

  • NewIdentExpression.ident = IDENT.lexval
  • NewExpression.node= NewIdentExpression.node NewExpression -> (int | boolean | void) NewArrayExpression
  • NewExpression.node = NewArrayExpression.node
  • NewArrayExpression.type = boolean | int | void

NewArrayExpression -> [Expression] ([])*

  • NewArrayExpression.type = new ArrayType(NewArrayExpression.type)
  • for all pairs of []
  • NewArrayExpression.type = new ArrayType(NewArrayExpression.type)
  • NewArrayExpression.node = new NewArrayExpression(NewArrayExpression.type, Expression.node)

NewIdentExpression -> () | NewArrayExpression

NewIdentExpression -> ()

  • NewIdentExpression.node = new NewObjectExpression(NewIdentExpression.ident) NewIdentExpression -> NewArrayExpression
  • NewIdentExpression.node = NewArrayExpression.node

BinaryExpression

Expression -> AssignmentExpression

  • Expression.node = AssignmentExpression.node

AssignmentExpression -> LogicalOrExpression AssignmentExpression'

  • AssignmentExpression'.in = LogicalOrExpression.node
  • AssignmentExpression.node = AssignmentExpression'.node

AssignmentExpression' -> epsilon

  • AssignmentExpression'.node = AssignmentExpression'.in

AssignmentExpression' -> = AssignmentExpression

  • AssignmentExpression'.node = new Assignment(AssignmentExpression'.in, AssignmentExpression.node)

LogicalOrExpression -> LogicalAndExpression LogicalOrExpression'

  • LogicalOrExpression'.in = LogicalAndExpression.node
  • LogicalOrExpression.node = LogicalOrExpression'.node

LogicalOrExpression' -> epsilon

  • LogicalOrExpression'.node = LogicalOrExpression'.in

LogicalOrExpression'1 -> || LogicalAndExpression LogicalOrExpression'2

  • LogicalOrExpression'2.in = new LogicalOr(LogicalOrExpression'1.in, LogicalAndExpression.node)
  • LogicalOrExpression'1.node = LogicalOrExpression'2.node

Equivalent to the LogicalOrExpression attributed grammar:

LogicalAndExpression -> EqualityExpression LogicalAndExpression'

LogicalAndExpression' -> (&& EqualityExpression LogicalAndExpression')?

EqualityExpression -> RelationalExpression EqualityExpression'

EqualityExpression' -> ((== | !=) RelationalExpression EqualityExpression')?

RelationalExpression -> AdditiveExpression RelationalExpression'

RelationalExpression' -> ((< | <= | > | >=) AdditiveExpression RelationalExpression')?

AdditiveExpression -> MultiplicativeExpression AdditiveExpression'

AdditiveExpression' -> ((+ | -) MultiplicativeExpression AdditiveExpression')?

MultiplicativeExpression -> UnaryExpression MultiplicativeExpression'

MultiplicativeExpression' -> ((* | / | %) UnaryExpression MultiplicativeExpression')?

Semantic analysis

UnaryExpression and following (for semantic analysis not AST construction)

NewArrayExpression :: Type Expression

  • if(Expression.type = int)
  • NewArrayExpression.type = new Array(Expression.value, Type.type)
  • NewArrayExpression.basictype = Type.type

NewObjectExpression :: Symbol

  • if(NewObjectExpression.umg.search(Symbol.ident))
  • NewObjectExpression.decl = NewObjectExpression.umg.search(Symbol.ident)
  • NewObjectExpression.type = class

NullExpression ::

  • NullExpression.type = null

ThisExpression ::

  • ThisExpression.decl = ThisExpression.umg.search(this.class)
  • ThisExpression.type = class

BooleanConstantExpression :: value

  • BooleanConstantExpression.value = value.booleanvalue

IntegerConstantExpression :: value

  • IntegerConstantExpression.value = value.intvalue

Symbol :: symbol

  • Symbol.value = symbol.lexvalue

VariableAccessExpression :: Expression Symbol

  • if(Expression.type = class)
  • VariableAccessExpression.decl = VariableAccessExpression.umg.search(Expression.value(Namespace), symbol.value)
  • VariableAccessExpression.type = VariableAccessExpression.decl.type
  • if(Expression.value = null)
  • VariableAccessExpression.decl = VariableAccessExpression.umg.search(this.class, symbol.value)
  • VariableAccessExpression.type = VariableAccessExpression.decl.type

MethodInvovationExpression :: Expression Symbol (Expression)*

  • if(Expression.type = class)
  • MethodInvovationExpression.decl = MethodInvovationExpression.umg.search(Expression.value(Namespace), symbol.value)
  • MethodInvovationExpression.returntype = MethodInvovationExpression.decl.returntype
  • MethodInvovationExpression.param = List<Expression> Expressions.value
  • if(Expression.value = null)
  • MethodInvovationExpression.decl = MethodInvovationExpression.umg.search(this.class, symbol.value)
  • MethodInvovationExpression.returntype = MethodInvovationExpression.decl.returntype
  • MethodInvovationExpression.param = List<Expression> Expressions.value

ArrayAccessExpression :: Expression1 Expression2

  • if(Expression1.type = array && Expression2.type = int)
  • ArrayAccessExpression.decl = ArrayAccessExpression.umg.search(Expression1.value)
  • ArrayAccessExpression.type = Expression1.basictype

LogicalNotExpression :: Expression

  • if(Expression.type = boolean)
  • LogicalNotExpression.type = boolean
  • LogicalNotExpression.value = !(Expression.value)

NegateExpression :: Expression

  • if(Expression.type = boolean)
  • NegateExpression.type = boolean
  • NegateExpression.value = -(Expression.value)
Clone this wiki locally