Skip to content

Attributed grammar

esonetec edited this page Nov 15, 2014 · 53 revisions

LAG(1) not possible, since methods can be used before they are declared.

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' | Member

MainMethod'.decls_in = ClassMember''.decls_in

ClassMember''.decls_out = MainMethod'.decls_out

ClassMember''.decls_out = Member.decls_out

Member.decls_in = Classmember''.decls_in

  • 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' -> ; | ( Parameters? ) Block

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

2. 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, boolean.lexval, void.lexval, IDENT.lexval

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

Statement.stmts = Block.stmts | EmptyStatement.stmts | IfStatement.stmts | ...

  • 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

BlockStatement.stmts_out = BlockStatement.stmts_in + IfStatement.node

...

  • 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 -> PostfixExpression | (! | -) UnaryExpression1

UnaryExpression.node = PostfixExpression.node

UnaryExpression.node = new LogicalNotExpression(UnaryExpression1.node)

UnaryExpression.node = new NegateExpression(UnaryExpression1.node)

  • PostfixExpression -> PrimaryExpression (PostfixOp)*

PostfixExpression.node = PostfixOp.node

PostfixOp.expr = PrimaryExpression.node

  • PostfixOp -> MethodInvocationFieldAccess | ArrayAccess

PostfixOp.node = MethodInvocationFieldAccess.node on "."

PostfixOp.node = ArrayAccess.node on "["

MethodInvocationFieldAccess.expr = PostfixOp.expr

ArrayAccess.expr = PostfixOp.expr

  • MethodInvocationFieldAccess -> . IDENT MethodInvocationFieldAccess'

MethodInvocationFieldAccess.node = MethodInvocationFieldAccess'.node

MethodInvocationFieldAccess'.expr = MethodInvocationFieldAccess.expr

MethodInvocationFieldAccess'.ident = IDENT.lexval

  • MethodInvocationFieldAccess' -> ( Arguments ) | epsilon

MethodInvocationFieldAccess'.node = new MethodInvocationExpression(MethodInvocationFieldAccess'.expr, MethodInvocationFieldAccess'.ident, Arguments.node)

MethodInvocationFieldAccess'.node = new VariableAccessExpression(MethodInvocationFieldAccess'.expr, 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

if(null) PrimaryExpression.node = new NullExpression()

if(this) PrimaryExpression.node = new ThisExpression()

if(boolean) PrimaryExpression.node = new BooleanConstantExpression(booleanvalue)

if(int) PrimaryExpression.node = new IntegerConstantExpression(intvalue)

if(() PrimaryExpression.node = Expression.node

if(IDENT) PrimaryExpression.node = PrimaryIdent.node PrimaryIdent.ident = IDENT.lexvalue

if(new) PrimaryExpression.node = NewExpression.node

  • PrimaryIdent -> ( Arguments ) | epsilon

if(() PrimaryIdent.node = new VariableAccessExpression(null, PrimaryIdent.ident)

else PrimaryIdent.node = new MethodInvocationExpression(null, PrimaryIdent.ident, Arguments.node)

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

if(IDENT) NewIdentExpression.ident = IDENT.lexval

NewExpression.node= NewIdentExpression.node

else NewExpression.node = NewArrayExpression.node

NewArrayExpression.type = boolean | int | void

  • NewArrayExpression -> [Expression] ([])*

NewArrayExpression.type = new ArrayType(NewArrayExpression.type)

for all [] pairs

NewArrayExpression.type = new ArrayType(NewArrayExpression.type)

NewArrayExpression.node = new NewArrayExpression(NewArrayExpression.type, Expression.node)

  • NewIdentExpression -> () | NewArrayExpression

if(() NewIdentExpression.node = new NewObjectExpression(NewIdentExpression.ident)

else NewIdentExpression.node = NewArrayExpression.node

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