Skip to content

Abstract Syntax Tree

Benjamin Kowarsch edited this page Jun 15, 2023 · 35 revisions

AST Specification

Non-Terminal Nodes

File Node

fileNode :=
  '(' FILE filenameNode moduleKeyNode moduleNode ')'
  ;

Module Nodes

moduleNode :=
  ifcModuleNode | impModuleNode | pgmModuleNode ;

Interface Module Node

ifcModuleNode :=
  '(' INTERFACE moduleIdentNode impListNode rxpListNode declListNode ')'
  ;

alias moduleIdentNode = identNode ;

Implementation Module Node

impModuleNode :=
  '(' IMPLEMENTATION moduleIdentNode impListNode defListNode blockNode ')'
  ;

Program Module Node

pgmModuleNode :=
  '(' PROGRAM moduleIdentNode impListNode defListNode blockNode ')'
  ;

Declaration List Node

declListNode :=
  '(' DECL-LIST defOrDeclNode+ ')'
  ;

Definition Or Declaration Node

defOrDeclNode :=
  constDefListNode | typeDefListNode |
  typeDeclListNode| varDeclListNode | procDeclListNode ;

Definition List Node

defListNode :=
  '(' DEF-LIST defNode+ ')'
  ;

Definition Node

defNode :=
  constDefNode | typeDefNode | varDefNode | procDefNode
  ;

Constant Definition Node

constDefNode :=
  '(' CONSTDEF identNode ( typeIdentNode | emptyNode ) exprNode ')'
  ;

alias typeIdentNode = identNode ;

Type Declaration Node

typeDeclNode :=
  '(' TYPEDECL identNode opaqueTypeNode ')'
  ;

Type Definition Node

typeDefNode :=
  '(' TYPEDEF identNode typeNode ')'
  ;

Type Node

typeNode :=
  derivedTypeNode | aliasTypeNode | subrTypeNode | enumTypeNode | setTypeNode |
  arrayTypeNode | recTypeNode | pointerTypeNode | procTypeNode
  ;

alias derivedTypeNode = typeIdentNode ;

Variable Declaration Node

varDeclNode :=
  '(' VARDECL identNode ( typeIdentNode | anonTypeNode ) ')'
  ;

Variable Definition Node

varDefNode :=
  '(' VARDEF identNode ( typeIdentNode | anonTypeNode ) ')'
  ;

Anonymous Type Node

anonTypeNode :=
  subrTypeNode | arrayTypeNode | procTypeNode
  ;

Procedure Declaration Node

procDeclNode :=
  '(' PROCDECL procSigNode ')'
  ;

Procedure Definition Node

procDefNode :=
  '(' PROCDEF procSigNode blockNode ')'
  ;

Constant Binding Node

constBindNode :=
  '(' BIND-CONST constIdentNode constBindSpecNode ')'
  ;

alias constIdentNode = identNode ;

Procedure Binding Node

procBindNode :=
  '(' BIND-PROC procIdentNode procBindSpecNode ')'
  ;

alias procIdentNode identNode ;

Procedure Signature Node

procSigNode :=
  '(' PSIG identNode formalParamListNode retTypeNode ')'
  ;

alias retTypeNode = typeIdentNode ;

Formal Parameter List Nodes

formalParamListNode := formalParamsNode | formalParamsSeqNode ;

Formal Parameters Sequence Node

formalParamsSeqNode :=
  '(' FPSEQ formalParamsNode+ ')'
  ;

Parameters Node

formalParamsNode := byvalParamsNode | byrefParamsNode | constParamsNode ;

BYVAL Formal Parameters Node

byvalParamsNode :=
  '(' BYVAL paramIdentListNode formalTypeNode ')'
  ;

paramIdentListNode := identNode | identListNode ;

BYREF Formal Parameters Node

byrefParamsNode :=
  '(' BYREF paramIdentListNode formalTypeNode ')'
  ;

CONSTREF Formal Parameters Node

constParamsNode :=
  '(' CONSTREF paramIdentListNode formalTypeNode ')'
  ;

Formal Type Nodes

formalTypeNode :=
  typeIdentNode | openArrayTypeNode | arglistTypeNode | castingTypeNode
  ;

Open Array Formal Type

openArrayTypeNode :=
  '(' OAP typeIdentNode ')'
  ;

ARGLIST Formal Type Node

arglistTypeNode :=
  '(' ARGLIST typeIdentNode ')'
  ;

CAST Formal Type Node

castingTypeNode :=
  '(' CAST castingType ')'
  ;

castingType := (IDENT "ADDRESS") | (IDENT "OCTETSEQ") ;

Alias Type Node

aliasTypeNode :=
  '(' ALIAS baseTypeNode ')'
  ;

alias baseTypeNode = typeIdentNode ;

Subrange Type Node

subrangeTypeNode :=
  '(' SUBR baseTypeNode rangeNode ')'
  ;

Range Node

rangeNode :=
  '(' RANGE lowerBound upperBound ')'
  ;

alias lowerBound, upperBound = exprNode ;

Enumeration Type Node

enumTypeNode :=
  '(' ENUM enumBaseTypeNode enumValueListNode ')'
  ;

enumBaseTypeNode := typeIdentNode | emptyNode ;

alias enumValueListNode = identListNode ;

Set Type Node

setTypeNode :=
  '(' SET baseTypeNode ')'
  ;

Array Type Node

arrayTypeNode :=
  '(' ARRAY baseTypeNode capacityNode ')'
  ;

alias capacityNode = intValueNode ;

Record Type Node

recordTypeNode :=
  '(' RECORD recBaseTypeNode fieldListSeqNode ')'
  ;

recBaseTypeNode := typeIdentNode | emptyNode ;

Field List Sequence Node

fieldListSeqNode :=
  '(' FIELD-LIST-SEQ fieldListNode+ ')'
  ;

alias fieldListNode = varDefNode ;

Pointer Type Node

pointerTypeNode :=
  '(' POINTER targetTypeNode ')'
  ;

alias targetTypeNode = qualidentNode ;

Opaque Type Node

opaqueTypeNode :=
  '(' OPAQUE allocSizeNode ')'
  ;

allocSizeNode = exprNode | emptyNode ;

Procedure Type Node

procTypeNode :=
  '(' PROC-TYPE formalTypeListNode retTypeNode ')'
  ;

Statement Sequence Node

stmtSeqNode :=
  '(' STMTSEQ statementNode+ ')'
  ;

Statement Nodes

statementNode :=
  assignStmtNode | copyStmtNode | procCallNode | returnStmtNode | newStmtNode |
  newArgStmtNode | newCapStmtNode | retainStmtNode | releaseStmtNode | ifStmtNode |
  caseStmtNode | loopStmtNode | whileStmtNode | repeatStmtNode | forStmtNode |
  readStmtNode | readNewStmtNode | writeStmtNode | writeFmtStmtNode | nopStmtNode
  ;

Assignment Statement Node

assignStmtNode :=
  '(' ASSIGN tgtDesigNode exprNode ')'
  ;

COPY Statement Node

copyStmtNode :=
  '(' COPY tgtDesigNode srcDesigNode ')'
  ;

Procedure Call Node

procCallNode :=
  '(' PCALL desigNode argsNode ')'
  ;

argsNode := exprListNode | emptyNode ;

RETURN Statement Node

returnStmtNode :=
  '(' RETURN exprNode ')'
  ;

NEW Statement Node

newStmtNode :=
  '(' NEW desigNode ')'
  ;

NEW ARGLIST Statement Node

newArgStmtNode :=
  '(' NEWARG desigNode srcDesigNode ')'
  ;

NEW CAPACITY Statement Node

newCapStmtNode :=
  '(' NEWCAP desigNode capacityNode ')'
  ;

alias capacityNode = exprNode ;

RETAIN Statement Node

retainStmtNode :=
  '(' RETAIN desigNode ')'
  ;

RELEASE Statement Node

releaseStmtNode :=
  '(' RELEASE desigNode ')'
  ;

IF Statement Node

ifStmtNode :=
  '(' IF exprNode stmtSeqNode elsifSeqNode elseStmtNode ')'
  ;

alias elseStmtNode = stmtSeqNode ;

ELSIF Sequence Node

elsifSeqNode :=
  '(' ELSIFSEQ elsifNode+ ')'
  ;

ELSIF Branch Node

elsifNode :=
  '(' ELSIF exprNode stmtSeqNode ')'
  ;

CASE Statement Node

caseStmtNode :=
  '(' SWITCH caseListNode+ ')'
  ;

LOOP Statement Node

loopStmtNode :=
  '(' LOOP stmtSeqNode ')'
  ;

WHILE Statement Node

whileStmtNode :=
  '(' WHILE exprNode stmtSeqNode ')'
  ;

REPEAT Statement Node

repeatStmtNode :=
  '(' REPEAT stmtSeqNode exprNode ')'
  ;

FOR Statement Node

forStmtNode :=
  '(' FOR loopVariantNode iterableNode stmtSeqNode ')'
  ;

EXIT Statement Node

exitStmtNode :=
  '(' EXIT ')'
  ;

READ Statement Node

readStmtNode :=
  '(' READ chanNode desigNode ')'
  ;

chanNode := identNode | qualidentNode ;

READ NEW Statement Node

readNewStmtNode :=
  '(' READNEW chanNode ptrDesigNode ')'
  ;

alias ptrDesigNode = desigNode ;

WRITE Statement Node

writeStmtNode :=
  '(' WRITE chanNode desigNode ')'
  ;

WRITE # Statement Node

writeFmtStmtNode :=
  '(' WRITEF chanNode fmtNode desigNode ')'
  ;

NOP Statement Node

nopStmtNode :=
  '(' NOP ')'
  ;

Expression Nodes

exprNode :=
  eqNode | neqNode | ltNode | lteqNode | gtNode | gteqNode | idtyNode | inNode |
  plusNode | minusNode | neqNode | concatNode | setDiffNode | orNode | starNode |
  slashNode | divNode | modNode | andNode | notNode | typeConvNode | subscrNode |
  derefNode | selectNode | funcCall
  ;

Equality Expression Node

eqNode :=
  '(' EQ leftNode rightNode ')'
  ;

alias leftNode, rightNode = exprNode ;

Inequality Expression Node

neqNode :=
  '(' NEQ leftNode rightNode ')'
  ;

Less-Than Expression Node

ltNode :=
  '(' LT leftNode rightNode ')'
  ;

Less-Than-Or-Equal Expression Node

lteqNode :=
  '(' LTEQ leftNode rightNode ')'
  ;

Greater-Than Expression Node

gtNode :=
  '(' GT leftNode rightNode ')'
  ;

Greater-Than-Or-Equal Expression Node

gteqNode :=
  '(' GTEQ leftNode rightNode ')'
  ;

Identity Expression Node

idtyNode :=
  '(' IDTY leftNode rightNode ')'
  ;

IN Expression Node

inNode :=
  '(' IN elemNode setNode ')'
  ;

alias elemNode, setNode = exprNode ;

Plus Expression Node

plusNode :=
  '(' '+' leftNode rightNode ')'
  ;

Minus Expression Node

minusNode :=
  '(' '-' leftNode rightNode ')'
  ;

Unary Minus Expression Node

negNode :=
  '(' NEG exprNode ')'
  ;

Plus Expression Node

plusNode :=
  '(' '+' leftNode rightNode ')'
  ;

Concatenation Expression Node

concatNode :=
  '(' CONCAT leftNode rightNode ')'
  ;

Set Difference Expression Node

setDiffNode :=
  '(' SETDIFF leftNode rightNode ')'
  ;

OR Expression Node

orNode :=
  '(' OR leftNode rightNode ')'
  ;

Asterisk Expression Node

starNode :=
  '(' '*' leftNode rightNode ')'
  ;

Solidus Expression Node

slashNode :=
  '(' '/' leftNode rightNode ')'
  ;

DIV Expression Node

divNode :=
  '(' DIV leftNode rightNode ')'
  ;

MOD Expression Node

modNode :=
  '(' MOD leftNode rightNode ')'
  ;

AND Expression Node

andNode :=
  '(' AND leftNode rightNode ')'
  ;

NOT Expression Node

notNode :=
  '(' NOT exprNode ')'
  ;

Type Conversion Expression Node

typeConvNode :=
  '(' TYPECONV exprNode typeIdentNode ')'
  ;

Subscript Expression Node

subscrNode :=
  '(' SUBSCR desigNode indexNode ')'
  ;

alias indexNode = exprNode ;

Dereference Expression Node

derefNode :=
  '(' DEREF exprNode ')'
  ;

Field Selection Expression Node

selectNode :=
  '(' SELECT desigNode desigNode ')'
  ;

Function Call Node

funcCallNode :=
  '(' FCALL desigNode argsNode ')'
  ;

Insert Designator Node

insertDesigNode :=
  '(' INSERT desigNode indexNode ')'
  ;

alias indexNode = exprNode ;

Slice Designator Node

sliceDesigNode :=
  '(' SLICE desigNode rangeNode ')'
  ;

Empty Node

emptyNode :=
  '( EMPTY ')'
  ;

Terminal Nodes

Filename Node

filenameNode :=
  '(' FILENAME '"' Filename '"' ')'
  ;

Filename := Basename '.' FileSuffix ;

Basename := Letter ( Letter | Digit )* ;

FileSuffix := 'def' | 'ifm' | 'mod' ;

Module Key Node

moduleKeyNode :=
  '(' KEY Base16IntValue ')'
  ;

Base16IntValue := '0x' Base16Digit+ ;

Import List Node

impListNode :=
  '(' IMPORT QuotedLibIdent+ ')'
  ;

QuotedLibIdent := '"' Letter ( Letter | Digit )* '"' ;

Re-Export List Node

rxpListNode :=
  '(' RE-EXPORT QuotedLibIdent+ ')'
  ;

Constant Binding Specifier Node

constBindSpecNode :=
  '(' IDENT ConstBindTarget ')'
  ;

ConstBindTarget := "COLLATION" | "TLIMIT" ;

Procedure Binding Specifier Node

procBindSpecNode :=
  '(' IDENT ProcBindTarget ')'
  ;

ProcBindTarget :=
  "NEW" | "NEWARG" | "NEWCAP" | "RETAIN" | "RELEASE" | "READ" | "READNEW" |
  "WRITE" | "WRITEF" | "ALLOC" | "APPEND" | "ATINSERT" | "ATREMOVE" |
  "ATSTORE" | "ATVALUE" | "COUNT" | "DEALLOC" | "FIRST" | "LAST" | "LENGTH" |
  "NEXT" | "PREV" | "REMOVE" | "STDIN" | "STDOUT" | "STORE" | "VALUE"
  ;

Identifier Node

identNode :=
  '(' IDENT IdentLexeme ')'
  ;

IdentLexeme := '"' Letter ( Letter | Digit )* '"' ;

Qualified Identifier Node

qualidentNode :=
  '(' QUALIDENT IdentLexeme+ ')'
  ;

Identifier List Node

identListNode :=
  '(' IDENT-LIST IdentLexeme+ ')'
  ;

Integer Value Node

intValNode :=
  '(' INTVAL IntValue ')'
  ;

IntValue := Base16IntValue | NonZeroDigit Digit* ;

Real Value Node

realValNode :=
  '(' IREALVAL realValue ')'
  ;

realValue := ( NonZeroDigit+ | '0' ) '.' Digit+ ( 'e' Digit+ )? ;

Character Value Node

charValueNode :=
  '(' CHRVAL chrValue ')'
  ;

chrValue := '0u' ( Digit | 'A' .. 'F' )+ ;

Quoted String Value Node

quotedValueNode :=
  '(' QUOTEDVAL quotedValue ')'
  ;

quotedValue := '"' ( PrintableChar | EscapeSeq )* '"' ;

PrintableChar := 0u20 .. 0u7F ;

EscapeSeq := '\' ('n' | 't' | '\') ;
Clone this wiki locally