You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdevelop/languages/pascal/pascal.tree.g

469 lines
8.0 KiB

//
// Pascal Tree Super Grammar (symtab.g derives from this)
//
// Adapted from,
// Pascal User Manual And Report (Second Edition-1978)
// Kathleen Jensen - Niklaus Wirth
//
// By
//
// Hakki Dogusan dogusanh@tr-net.net.tr
//
// Then significantly enhanced by Piet Schoutteten
// with some guidance by Terence Parr. Piet added tree
// construction, and some tree walkers.
//
//
// Adopted to KDevelop by Alexander Dymo <cloudtemple@mksat.net>
//
header "pre_include_hpp" {
#include <codemodel.h>
#include "PascalAST.h"
#include <qstring.h>
#include <qstringlist.h>
#include <qfileinfo.h>
}
header "post_include_hpp" {
#include <codemodel.h>
#include <kdebug.h>
}
options {
language="Cpp";
}
class PascalStoreWalker extends TreeParser;
options {
importVocab = Pascal;
defaultErrorHandler = true;
ASTLabelType = "RefPascalAST";
}
{
private:
TQString m_fileName;
QStringList m_currentScope;
int m_currentAccess;
int m_anon;
CodeModel* m_model;
public:
void setCodeModel( CodeModel* model ) { m_model = model; }
CodeModel* codeModel() { return m_model; }
const CodeModel* codeModel() const { return m_model; }
TQString fileName() const { return m_fileName; }
void setFileName( const TQString& fileName ) { m_fileName = fileName; }
void init(){
m_currentScope.clear();
m_currentAccess = CodeModelItem::Public;
m_anon = 0;
}
void wipeout() { m_model->wipeout(); }
}
program
: programHeading
block
;
programHeading
: #(PROGRAM IDENT identifierList)
| #(UNIT IDENT)
;
identifier
: IDENT
;
block
: ( labelDeclarationPart
| constantDefinitionPart
| typeDefinitionPart
| variableDeclarationPart
| procedureAndFunctionDeclarationPart
| usesUnitsPart
| IMPLEMENTATION
)*
compoundStatement
;
usesUnitsPart
: #(USES identifierList)
;
labelDeclarationPart
: #(LABEL ( label )+)
;
label
: NUM_INT
;
constantDefinitionPart
: #(CONST ( constantDefinition )+ )
;
constantDefinition
: #(EQUAL IDENT constant)
;
constant
: NUM_INT
| NUM_REAL
| #( PLUS
( NUM_INT
| NUM_REAL
| IDENT
)
)
| #( MINUS
( NUM_INT
| NUM_REAL
| IDENT
)
)
| IDENT
| STRING_LITERAL
| #(CHR (NUM_INT|NUM_REAL))
;
string
: STRING_LITERAL
;
typeDefinitionPart
: #(TYPE ( typeDefinition )+)
;
typeDefinition
: #(TYPEDECL IDENT
( type
| #(FUNCTION (formalParameterList)? resultType)
| #(PROCEDURE (formalParameterList)?)
)
)
;
type
: #(SCALARTYPE identifierList)
| #(DOTDOT constant constant)
| typeIdentifier
| structuredType
| #(POINTER typeIdentifier)
;
typeIdentifier
: IDENT
| CHAR
| BOOLEAN
| INTEGER
| REAL
| #( STRING
( IDENT
| NUM_INT
| NUM_REAL
|
)
)
;
structuredType
: #(PACKED unpackedStructuredType)
| unpackedStructuredType
;
unpackedStructuredType
: arrayType
| recordType
| setType
| fileType
;
/** Note here that the syntactic diff between brackets disappears.
* If the brackets mean different things semantically, we need
* two different alternatives here.
*/
arrayType
: #(ARRAY typeList type)
;
typeList
: #( TYPELIST ( type )+ )
;
recordType
: #(RECORD fieldList)
;
fieldList
: #( FIELDLIST
( fixedPart ( variantPart )?
| variantPart
)
)
;
fixedPart
: ( recordSection )+
;
recordSection
: #(FIELD identifierList type)
;
variantPart
: #( CASE tag ( variant )+ )
;
tag
: #(VARIANT_TAG identifier typeIdentifier)
| #(VARIANT_TAG_NO_ID typeIdentifier)
;
variant
: #(VARIANT_CASE constList fieldList)
;
setType
: #(SET type)
;
fileType
: #(FILE (type)?)
;
/** Yields a list of VARDECL-rooted subtrees with VAR at the overall root */
variableDeclarationPart
: #( VAR ( variableDeclaration )+ )
;
variableDeclaration
: #(VARDECL identifierList type)
;
procedureAndFunctionDeclarationPart
: procedureOrFunctionDeclaration
;
procedureOrFunctionDeclaration
: procedureDeclaration
| functionDeclaration
;
procedureDeclaration
: #(PROCEDURE IDENT (formalParameterList)? block )
;
formalParameterList
: #(ARGDECLS ( formalParameterSection )+)
;
formalParameterSection
: parameterGroup
| #(VAR parameterGroup)
| #(FUNCTION parameterGroup)
| #(PROCEDURE parameterGroup)
;
parameterGroup
: #(ARGDECL identifierList typeIdentifier)
;
identifierList
: #(IDLIST (IDENT)+)
;
constList
: #(CONSTLIST ( constant )+)
;
functionDeclaration
: #(FUNCTION IDENT (formalParameterList)? resultType block)
;
resultType
: typeIdentifier
;
statement
: #(COLON label unlabelledStatement)
| unlabelledStatement
;
unlabelledStatement
: simpleStatement
| structuredStatement
;
simpleStatement
: assignmentStatement
| procedureStatement
| gotoStatement
;
assignmentStatement
: #(ASSIGN variable expression)
;
/** A variable is an id with a suffix and can look like:
* id
* id[expr,...]
* id.id
* id.id[expr,...]
* id^
* id^.id
* id^.id[expr,...]
* ...
*
* LL has a really hard time with this construct as it's naturally
* left-recursive. We have to turn into a simple loop rather than
* recursive loop, hence, the suffixes. I keep in the same rule
* for easy tree construction.
*/
variable
: #(LBRACK variable (expression)+)
| #(LBRACK2 variable (expression)+)
| #(DOT variable IDENT)
| #(POINTER variable)
| #(AT IDENT)
| IDENT
;
expression
: #(EQUAL expression expression)
| #(NOT_EQUAL expression expression)
| #(LTH expression expression)
| #(LE expression expression)
| #(GE expression expression)
| #(GT expression expression)
| #(IN expression expression)
| #(PLUS expression (expression)?)
| #(MINUS expression (expression)?)
| #(OR expression expression)
| #(STAR expression expression)
| #(SLASH expression expression)
| #(DIV expression expression)
| #(MOD expression expression)
| #(AND expression expression)
| #(NOT expression)
| variable
| functionDesignator
| set
| NUM_INT
| NUM_REAL
| #(CHR (NUM_INT|NUM_REAL))
| string
| NIL
;
functionDesignator
: #(FUNC_CALL IDENT (parameterList)?)
;
parameterList
: #( ARGLIST (actualParameter)+ )
;
set
: #(SET (element)*)
;
element
: #(DOTDOT expression expression)
| expression
;
procedureStatement
: #(PROC_CALL IDENT ( parameterList )?)
;
actualParameter
: expression
;
gotoStatement
: #(GOTO label)
;
structuredStatement
: compoundStatement
| conditionalStatement
| repetetiveStatement
| withStatement
;
compoundStatement
: statements
;
statements
: #(BLOCK (statement)*)
;
conditionalStatement
: ifStatement
| caseStatement
;
ifStatement
: #(IF expression statement (statement)?)
;
caseStatement //pspsps ???
: #(CASE expression
( caseListElement )+
( statements )?
)
;
caseListElement
: #(COLON constList statement)
;
repetetiveStatement
: whileStatement
| repeatStatement
| forStatement
;
whileStatement
: #(WHILE expression statement)
;
repeatStatement
: #(REPEAT statements expression)
;
forStatement
: #(FOR IDENT forList statement)
;
forList
: #(TO initialValue finalValue)
| #(DOWNTO initialValue finalValue)
;
initialValue
: expression
;
finalValue
: expression
;
withStatement
: #(WITH recordVariableList statement)
;
recordVariableList
: ( variable )+
;