# Predefined functions:

Function name | Occurence
charAt(...) | 39
composeHTMLLikeString(...) | 7
endString(...) | 9
endl(...) | 19
existVariable(...) | 11
findElement(...) | 2
findFirstChar(...) | 39
first(...) | 12
getFloatingLocation(...) | 23
getMarkupKey(...) | 1
getProperty(...) | 3
getWorkingPath(...) | 11
isEmpty(...) | 6
isNegative(...) | 39
newFloatingLocation(...) | 12
not(...) | 72
startString(...) | 39
subString(...) | 39
toUpperString(...) | 39

# Procedures:

Instruction name | Occurence
__RAW_TEXT_TO_WRITE(...) | 498
clearVariable(...) | 1
expand(...) | 1
generate(...) | 9
insertTextOnce(...) | 24
parseAsBNF(...) | 1
setCommentBegin(...) | 1
setCommentEnd(...) | 1
setProtectedArea(...) | 19
traceLine(...) | 5
translate(...) | 1
writeText(...) | 325

# File "GettingStarted/CppObjectBody.cwt":

//note: Visual C++-specific pragma must be added to prevent from intempestive warnings
//note: about template class instantiation of \samp{std::vector<\textit{T}>} in DEBUG mode!
#ifdef WIN32
#pragma warning(disable : 4786)
#endif
@
//note: the developer will add here all include files he will need for implementation of
//note: methods,
[3]setProtectedArea("include files");
@
#include "@
//note: the header of this body is compulsory,
//merge:
[3]this.name@.h"
[3]@this.name@::@this.name@()@
//note: this part concerns the initialization of attributes. Some attributes, such as strings
//note: and vectors of the STL don't require to be initialized explicitly. It justifies the
//note: declaration of variable \samp{bAtLeastOne} that is worth \samp{false} as long as
//note: no attribute has been initialized yet. We'll see why below.
[3]local bAtLeastOne = false;
[3]foreach i in this.listOfAttributes {
//note: arrays and strings are skipped,
[1] if !i.type.isArray && (i.type.name != "string") {
if bAtLeastOne {
//note: if it isn't the first attribute to be initialized, a comma make a separation with
//note: the precedent,
@, @
[1] } else {
//note: if it is the first attribute to be initialized, a colon is expected to announce
//note: the beginning of initializations
@ : @
//note: now, there is at least one attribute to be initialized,
[1] set bAtLeastOne = true;
}
[1] @_@getVariableName(i.name, i.type)@(@
//note: attribute is populated with the default value corresponding to its type,
if i.type.isObject {
@0L@
[1] } else {
[1] switch(i.type.name) {
case "int":
@0@
break;
case "double":
@0.0@
[1] break;
case "boolean":
@false@
break;
}
}
@)@
}
}
@ {
}
[3]@this.name@::~@this.name@() {
@
//note: aggregated objects must be deleted before leaving this instance,
[3]foreach i in this.listOfAttributes {
[1] if i.type.isAggregation && i.type.isObject {
[1] local sAttributeName = "_" + getVariableName(i.name, i.type);
[1] local sIndex = "iterate" + normalizeIdentifier(i.name);
[1] if i.type.isArray {
//note: all elements of an aggregated array must be deleted
[1] @ for (std::vector<@i.name@*>::const_iterator @sIndex@ = @sAttributeName@.begin(); @sIndex@ != @sAttributeName@.end(); ++@sIndex@) {
[1] delete *@sIndex@;
}
@
} else {
//note: the aggregated object is deleted
@ delete @sAttributeName@;
@
}
}
}
@}
@
//note: implementation of all methods,
[3]foreach i in this.listOfMethods {
//note: the return type of the method is translated to C++,
[1] if existVariable(i.type) {
[1] @@getType<"C++">(i.type)@@
} else {
@void@
}
[1] @ @this.name@::@i.name@(@
//note: parameters of the method are iterated to be written in C++
[1] foreach j in i.listOfParameters {
//note: if iterator \samp{j} doesn't point to the first parameter, a comma makes a
//note: separation with the precedent,
[2] if !first(j) {
@, @
}
[3] @@getParameterType<"C++">(j.type, j.mode)@ @getVariableName(j.name, j.type)@@
}
@) {
@
//note: a protected area is inserted, whose key is the method ID,
[1] setProtectedArea(getMethodID(i));
@}
@
}

# File "GettingStarted/CppObjectHeader.cwt":

User defined function | Occurence | Time in ms
populateHeaderDeclarations(...) at 29 | 7 | 0

#ifndef _@
//note: the value of attribute \samp{\textit{this.}name} is written to the output file, where
//note: \samp{\textit{this}} points to a node that describes the current class. Note that
//note: \samp{\textit{this}} is facultative, and is assigned by the caller of procedure
//note: \samp{generate} that runs this script.
//merge:
[3]this.name@_h_
[3]#define _@this.name@_h_
@
//note: put one anchor for including all files that we'll encounter as compulsory, while
//note: iterating attributes or methods. Example: if an attribute is an array, we'll need
//note: to include the STL header \textit{vector} at this position of the file:
//note: \textit{\#include }. This insertion point is called \samp{"include files"}.
[3]newFloatingLocation("include files");
//note: to avoid that the two floating locations \samp{"include files"} and \samp{"class declarations"}
//note: (described just below) point to the same file position, an empty line is added,
@
// this line separates the two insertion points, so as to distinguish them!
@
//note: put one anchor for announcing all classes that we'll encounter as referenced, while
//note: iterating attributes or methods. Example: if an attribute is an object
//note: \textit{Planet}, we'll need to write \textit{class Planet;} at this position of
//note: the file. This insertion point is called \samp{"class declarations"}.
[3]newFloatingLocation("class declarations");
//note: this function is called on every type encountered while iterating attributes and methods.
//note: Its role is to populate the \samp{"include files"} and \samp{"class declarations"} areas.
[7]function populateHeaderDeclarations(myType : node) {
//note: the type of an object must be declared at the beginning of the header, otherwise
//note: the compiler will not recognize it : the class is declared \textbf{once only} in
//note: the insertion point called \samp{"class declarations"}. Use of function \samp{insertTextOnce}
//note: assures that if this class has already been inserted before, it will not be twice.
[1] if myType.isObject insertTextOnce(getFloatingLocation("class declarations"), "class " + myType.name + ";" + endl());
//note: this type is an array, so the declaration of \samp{std::vector} must be included
//note: to the insertion point called \samp{"include files"},
[2] if myType.isArray insertTextOnce(getFloatingLocation("include files"), "#include " + endl());
//note: this type is a string, so the declaration of \samp{std::string} must be included
//note: to the insertion point called \samp{"include files"},
[7] if myType.name insertTextOnce(getFloatingLocation("include files"), "#include " + endl());
}
@
[3]class @this.name@ @
//note: if the class inherits from a parent class, this relationship must be written,
[1]if existVariable(this.parent) {
//note: the parent class must be declared,
[1] insertTextOnce(getFloatingLocation("include files"), "#include \"" + this.parent.name +".h\"" + endl());
[1] @: public @this.parent.name@ @
}
@{
private:
@
//note: declaration of all attributes,
[3]foreach i in this.listOfAttributes {
//note: does the type of the attribute need some backward declarations?
[3] populateHeaderDeclarations(i.type);
[3] @ @getType<"C++">(i.type)@ _@getVariableName(i.name, i.type)@;
@
}
@
public:
[3] @this.name@();
[3] ~@this.name@();
// accessors:
@
//note: accessors to each attribute,
[3]foreach i in this.listOfAttributes {
[3] local sVariableName = getVariableName(i.name, i.type);
//note: there are two symbols to swap between writing a sequence of characters and
//note: interpreting script ; we have used the symbol \textbf{'@'}, and now we illustrate
//note: the use of tags \textbf{'<\%} and \textbf{'\%>},
[3] %> inline <%getType<"C++">(i.type)%> get<%normalizeIdentifier (i.name)%>() const { return _<%sVariableName%>; }
inline void set<%
//note: you can melt the two swapping symbol, but it is more difficult to read, so not
//note: very interesting!
//merge:
[3]normalizeIdentifier(i.name)@(<%getType <"C++">(i.type)%> <%sVariableName@) { _<%sVariableName%> = <%sVariableName%>; }
@
}
@
// methods:
@
//note: declaration of all methods,
[3]foreach i in this.listOfMethods {
//note: each method might be overloaded by subclasses,
@ virtual @
//note: the return type of the method is translated to C++,
[1] if existVariable(i.type) {
//note: does the return type of the method need some backward declarations?
[1] populateHeaderDeclarations(i.type);
//note: expression \samp{getType<"C++">(i.type)} to evaluate is embedded between double
//note: \textbf{'@'}. The first one allow swapping to the \textit{sequence of characters}
//note: mode, but there is no characters to write. The second one allows swapping to the
//note: \textit{script} mode, which is reduced just to evaluate the expression. The two
//note: final \textbf{'@'} take the same role as seen before.
[1] @@getType<"C++">(i.type)@@
} else {
@void@
}
[1] @ @i.name@(@
//note: parameters of the method are iterated to be written in C++
[1] foreach j in i.listOfParameters {
//note: if iterator \samp{j} doesn't point to the first parameter, a comma makes a
//note: separation with the precedent,
[2] if !first(j) {
@, @
}
//note: does the type of the parameter need some backward declarations?
[3] populateHeaderDeclarations(j.type);
[3] @@getParameterType<"C++">(j.type, j.mode)@ @getVariableName(j.name, j.type)@@
}
@);
@
}
@
private:
[3] @this.name@(const @this.name@&);
[3] @this.name@& operator =(const @this.name@&);
};
#endif

# File "GettingStarted/HTML2LaTeX.cwp":

#noCase
[1]HTML2LaTeX ::= #ignore(HTML) #continue '<' "HTML" '>' HTMLHeader HTMLBody '<' '/' "HTML" '>' #empty;
HTMLHeader ::= '<' #continue "HEAD" '>' [~['<' '/' "HEAD" '>']]* '<' '/' "HEAD" '>';
HTMLBody ::= '<' #continue "BODY" '>' HTMLText '<' '/' "BODY" '>';
//note: blank characters are interesting, so we refuse to ignore HTML blanks and comments,
HTMLText ::= #!ignore
[
//note: handling of HTML escape sequences, announced by character \textbf{'\&'},
'&' #continue #readIdentifier:sEscape HTMLEscape ';'
|
//note: if not the beginning of a tag, the current character of the input stream
//note: is put to the output stream,
~'<':cChar => writeText(cChar);
|
//note: token operator '!' doesn't move the position of the input stream, and it continues
//note: in sequence only if the token expression that follows doesn't match; here, we check
//note: whether we have reached an end of tag or not,
!['<' blanks '/']
[
//note: we do not ignore comments anymore, so we have to do it my ourselves,
""]* "-->"
|
//note: an embedded tag has been encountered,
'<' #continue #ignore(HTML) #readIdentifier:sTag HTMLNextOfTag
]
]*;
//note: template clauses \samp{HTMLEscape<\textit{T}>} are always valid and just convert
//note: special characters to their LaTeX representation,
HTMLEscape<"lt"> ::= => {@<@};
HTMLEscape<"gt"> ::= => {@>@};
HTMLTag(sTag : value) ::= '<' #readText(sTag) #continue HTMLNextOfTag;
//note: in the real life, HTML tag \textit{

# } could represent a chapter, but the LaTeX

//note: output file is intended to be included into the reference manual of \CodeWorker\ as
//note: an illustration ; it will be a part of a section, so chapters are translated as
//note: sub sections!
HTMLNextOfTag<"H1"> ::=
#continue '>' => {@\subsection{@}
HTMLText
'<' '/' "H1" '>' => {@}@};
//note: in the real life, HTML tag \textit{

## } could represent a section, but for the same

//note: reason as above, it will be translated as a sub-sub section,
HTMLNextOfTag<"H2"> ::=
#continue '>' => {@\subsubsection{@}
HTMLText
'<' '/' "H2" '>' => {@}@};
HTMLNextOfTag<"A"> ::= [HTMLAttribute]* #continue '>' HTMLText '<' '/' 'A' '>';
HTMLNextOfTag<"TABLE"> ::=
[HTMLAttribute]* #continue '>' => {
@\begin{table@
//note: with HTML, the number of columns the table expects is deduced later. However, a
//note: latex table (well-formed for a PDF conversion) must know explicetly of how many
//note: columns it is composed. So, a floating position is attached to the current position
//note: of the output file. While discovering columns, text will be inserted here and further.
newFloatingLocation("table PDF suffix");
@}{@
//note: the format of each column is specified at this place,
newFloatingLocation("table columns");
@}{.5}@
}
//note: we consider that the first line of the table gives the name of the columns, and we'll
//note: take the PDF table suffix ('ii' for 2 columns, 'iii' for 3 columns, ...) to write
//note: lines of the table correctly,
=> local sPDFTableSuffix;
HTMLTableTitle(sPDFTableSuffix)
//note: we translate as many lines of the table as we can read, knowing the PDF suffix,
[HTMLTableLine(sPDFTableSuffix)]*
'<' '/' "TABLE" '>' => {@\end{table@sPDFTableSuffix@}
@};
HTMLTableTitle(sPDFTableSuffix : node) ::=
'<' "TR" [HTMLAttribute]*
#continue '>'
[HTMLTableCol(sPDFTableSuffix)]*
'<' '/' "TR" '>' => {
insertText(getFloatingLocation("table PDF suffix"), sPDFTableSuffix);
writeText(endl());
};
//note: the clause is intended to read the name of a column of a table, and to translate it
//note: to LaTeX, knowing that some text must be inserted into the declarative part of the
//note: LaTeX table,
HTMLTableCol(sPDFTableSuffix : node) ::=
'<' "TD" [HTMLAttribute]* #continue '>' => {
@{@
if !sPDFTableSuffix insertText(getFloatingLocation("table columns"), "l");
else insertText(getFloatingLocation("table columns"), "|l");
set sPDFTableSuffix += "i";
}
'<' 'B' '>' [#!ignore [~'<':cChar => writeText(cChar);]*] '<' '/' 'B' '>'
'<' '/' "TD" '>' => {@}@};
HTMLTableLine(sPDFTableSuffix : value) ::=
'<' "TR" [HTMLAttribute]* #continue '>' => {@\line@sPDFTableSuffix@@}
[HTMLTag("TD")]* '<' '/' "TR" '>' => {writeText(endl());};
HTMLNextOfTag<"TD"> ::=
[HTMLAttribute]* #continue '>' => {@{@}
HTMLCellText '<' '/' "TD" '>' => {@}@};
//note: the text into a cell of a table shouldn't contain paragraph jumps (empty line in LaTeX),
HTMLCellText ::= #!ignore
[
'&' #continue #readIdentifier:sEscape HTMLEscape ';'
|
//note: the simplest way to avoid empty lines is to ignore end of lines, and to replace it to
//note: a space,
['\r']? ['\n'] => {@ @}
|
~'<':cChar => writeText(cChar);
|
!['<' blanks '/']
[
""]* "-->"
|
'<' #continue #ignore(HTML) #readIdentifier:sTag HTMLNextOfTag
]
]*;
HTMLNextOfTag<"UL"> ::=
[HTMLAttribute]* #continue '>' => {@\begin{itemize}
@}
[HTMLTag("LI")]*
'<' '/' "UL" '>' => {@\end{itemize}
@};
HTMLNextOfTag<"LI"> ::=
[HTMLAttribute]* #continue '>' => {@\item @}
HTMLText
'<' '/' "LI" '>' => {writeText(endl());};
HTMLNextOfTag<"B"> ::=
#continue '>' => {@\textbf{@}
HTMLText
'<' '/' "B" '>' => {@}@};
HTMLNextOfTag<"I"> ::=
#continue '>' => {@\textbf{@}
HTMLText
'<' '/' "I" '>' => {@}@};
HTMLNextOfTag<"FONT"> ::= [HTMLAttribute]* #continue '>' HTMLText '<' '/' "FONT" '>';
HTMLNextOfTag<"BR"> ::= ['/']? #continue '>' => { writeText(endl());};
HTMLAttribute ::= #readIdentifier ['=' #continue [STRING_LITERAL | WORD_LITERAL]]?;
blanks ::= [' '| '\t' | '\r' | '\n']*;
STRING_LITERAL ::= #!ignore '\"' [~'\"']* '\"';
WORD_LITERAL ::= #!ignore [~['>' | '/' | ' ' | '\t']]+;

# File "GettingStarted/HTMLDocumentation.cwt":

@
//note: the predefined function \samp{getMarkupKey()} returns the name of the markup
//note: to expand,
[1]if getMarkupKey() == "classes presentation" {
//note: the markup is worth "classes presentation", and so, we'll describe all classes
[1] foreach i in project.listOfClasses {
@
[3]

## @i.name@

@
//note: a protected area is embedded here, which has to be populated by hand into the
//note: expanded file for describing the class,
[3] setProtectedArea(i.name + ":presentation");
[3] if !isEmpty(i.listOfAttributes) {
//note: attributes are presented into a table,
@

Type
Attribute name
Description
@
[3] foreach j in i.listOfAttributes {
//note: the language into which types have to be expressed is given by \samp{this.language},
//note: and is worth "C++" or "JAVA" ; don't forget to convert the type to the HTML syntax,
//note: because of \textbf{'<'} or \textbf{'>'} to convert respectively to \textbf{'\<'}
//note: or \textbf{'\>'} for instance. Use the predefined function
//note: \samp{composeHTMLLikeString()} to do this process.
@
[3] @composeHTMLLikeString(getType (j.type))@
[3] @j.name@
@
//note: a protected area is embedded here, which has to be populated by hand into the
//note: expanded file for describing the attribute,
[3] setProtectedArea(i.name + "::" + j.name + ":description");
@
@
}
@
@
}
[1] if !isEmpty(i.listOfMethods) {
@

@
[1] foreach j in i.listOfMethods {
//note: methods are presented into unordered lists,
@
- @
[1] if existVariable(j.type) {
[1] @function @composeHTMLLikeString(getType (j.type))@ @
} else {
@procedure@
}
[1] @@j.name@(@
[1] foreach k in j.listOfParameters {
[2] if !first(k) {
@, @
}
[3] @@composeHTMLLikeString(getParameterType (k.type, k.mode))@ @getVariableName(k.name, k.type)@@
}
@)
@
//note: a protected area is embedded here, which has to be populated by hand into the
//note: expanded file for describing the method,
[1] setProtectedArea(i.name + "::" + getMethodID(j) + ":description");
@
@
}
@
@
}
}
}

# File "GettingStarted/JAVAObject.cwt":

package solarsystem;
[3]public class @this.name@ @
//note: if the class inherits from a parent class, this relationship must be written,
[1]if existVariable(this.parent) {
[1] @extends @this.parent.name@ @
}
@{
@
//note: declaration of all attributes,
[3]foreach i in this.listOfAttributes {
[3] @ private @getType<"JAVA">(i.type)@ _@getVariableName(i.name, i.type)@;
@
}
@
[3] public @this.name@() {}
// accessors:
@
//note: accessors to each attribute,
[3]foreach i in this.listOfAttributes {
[3] local sVariableName = getVariableName(i.name, i.type);
[3] @ public @getType<"JAVA">(i.type)@ get@normalizeIdentifier(i.name)@() { return _@sVariableName@; }
[3] public void set@normalizeIdentifier(i.name)@(@getType<"JAVA">(i.type)@ @sVariableName@) { _@sVariableName@ = @sVariableName@; }
@
}
@
// methods:
@
//note: declaration of all methods,
[3]foreach i in this.listOfMethods {
@ public @
[1] if existVariable(i.type) {
[1] @@getType<"JAVA">(i.type)@@
} else {
@void@
}
[1] @ @i.name@(@
[1] foreach j in i.listOfParameters {
[2] if !first(j) {
@, @
}
[3] @@getParameterType<"JAVA">(j.type, j.mode)@ @getVariableName(j.name, j.type)@@
}
@) {
@
[1] setProtectedArea(getMethodID(i));
@ }
@
}
@}

# File "GettingStarted/LeaderScript6.cws":

//command: -I Scripts/Tutorial -path .
//command: -define DESIGN_FILE=GettingStarted/SolarSystem0.sml
//command: -script GettingStarted/LeaderScript6.cws
//command: -quantify Scripts/Tutorial/GettingStarted/quantify.html
[1]if !getProperty("DESIGN_FILE")
error("'-define DESIGN_FILE=file' expected on the command line");
[1]traceLine("'Simple Modeling' design file to parse = \""
+ getProperty("DESIGN_FILE") + "\"");
//hide:
[1]clearVariable(project.listOfClasses);
[1]parseAsBNF("GettingStarted/SimpleML-parsing.cwp",
project, getProperty("DESIGN_FILE"));
#include "TreeDecoration.cws"
#include "SharedFunctions.cws"
[1]foreach myClass in project.listOfClasses {
[3] traceLine("generating class '" + myClass.name + "' ...");
[3] generate("GettingStarted/CppObjectHeader.cwt", myClass, getWorkingPath() + "Scripts/Tutorial/GettingStarted/Cpp/" + myClass.name + ".h");
[3] generate("GettingStarted/CppObjectBody.cwt", myClass, getWorkingPath() + "Scripts/Tutorial/GettingStarted/Cpp/" + myClass.name + ".cpp");
[3] generate("GettingStarted/JAVAObject.cwt", myClass, getWorkingPath() + "Scripts/Tutorial/GettingStarted/JAVA/solarsystem/" + myClass.name + ".java");
}
[1]local myDocumentationContext;
[1]insert myDocumentationContext.language = "C++";
[1]traceLine("generating the HTML documentation...");
[1]setCommentBegin("");
[1]expand("GettingStarted/HTMLDocumentation.cwt",
myDocumentationContext, getWorkingPath()
+ "Scripts/Tutorial/GettingStarted/SolarSystem1.html");
[1]translate("GettingStarted/HTML2LaTeX.cwp", project, "GettingStarted/SolarSystem1.html", getWorkingPath() + "Scripts/Tutorial/GettingStarted/SolarSystem.tex");

# File "GettingStarted/SimpleML-parsing.cwp":

// syntactical clauses:
//note: the pattern \textit{[class_declaration]*} always matches with the parsed file,
//note: so the rule will continue in sequence in any case (supposing that no error has
//note: occurred into clause \textit{class_declaration}) and the end of file will be
//note: checked. If not reached, it doesn't write the message \samp{"file read successfully"},
[1]world ::= #ignore(C++) [class_declaration]* #empty
=> {
traceLine("file parsed successfully");
saveProject("Scripts/Tutorial/SolarSystem0.xml");
};
//note: once keyword \samp{"class"} has been matched, there is no ambiguity : we are
//note: handling a class declaration and the rule must continue in sequence. To require
//note: that, instruction \samp{\#continue} is written after pattern \samp{"class"}.
//note: If a pattern of the sequence doesn't match the parsed file, the parser throws
//note: a syntax error automatically.
class_declaration ::= IDENT:"class" #continue
//note: the identifier that matches with clause call \textit{IDENT} is assigned to
//note: the local variable \samp{sClassName} : on contrary of other types of script,
//note: a new variable is considered as local, instead of an new attribute added to
//note: the current node \samp{\textbf{this}},
IDENT:sClassName
//note: about parsing, classes are modeled into node
//note: \textbf{project.listOfClasses[}\textit{sClassName}\textbf{]}. Its attribute
//note: \samp{name} contains the value of \textit{sClassName}.
=> insert project.listOfClasses[sClassName].name = sClassName;
//note: if the class inherits from a parent, \samp{\textbf{':'}} is necessary followed by
//note: an identifier (pattern \samp{\#continue}), and the identifier that matches with
//note: clause call \textit{IDENT} is assigned to the local variable \samp{sClassName},
[':' #continue IDENT:sParentName
//note: this class inherits from a parent, so the optional attribute \samp{parent}
//note: of the class is populated with the value of \textit{sParentName},
=> insert project.listOfClasses[sClassName].parent = sParentName;
]?
class_body(project.listOfClasses[sClassName]);
//note: clause \samp{class_body} expects an argument: the class node into which the
//note: class members must be described (\samp{myClass : \textbf{node}}),
class_body(myClass : node) ::= '{'
[attribute_decl(myClass) | method_decl(myClass)]* '}';
//note: the class is populated with the characteristics of the attribute once
//note: its declaration has finished. Otherwise, it may confuse with the beginning
//note: of a method declaration. To avoid this ambiguity, we should have factorized
//note: the type declaration and the name of the member into a common clause, for
//note: example.
attribute_decl(myClass : node) ::=
=> local myType;
type_specifier(myType) IDENT:sAttributeName ';'
=> {
//note: about parsing, attributes are modeled into node
//note: \textbf{myClass.listOfAttributes[}\textit{sAttributeName}\textbf{]},
insert myClass.listOfAttributes[sAttributeName].name = sAttributeName;
//note: the type is allocated on the stack, so it is copied into branch \samp{type}
//note: (no node reference) integrally,
setall myClass.listOfAttributes[sAttributeName].type = myType;
};
//note: the class is populated with the characteristics of the method once
//note: the opened parenthesis is recognized,
method_decl(myClass : node) ::=
=> local myType;
[IDENT:"void" | type_specifier(myType)]
IDENT:sMethodName '('
//note: from here, there is no doubt that we are parsing a method declaration,
#continue
=> {
//note: about parsing, methods are modeled into node
//note: \textbf{myClass.listOfMethods[}\textit{sMethodName}\textbf{]},
insert myClass.listOfMethods[sMethodName].name = sMethodName;
//note: attribute \samp{name} is compulsory into a \textit{type} node, so if
//note: condition \samp{myType.name} returns \samp{false}, there is no return
//note: type (\samp{void}),
if myType.name
setall myClass.listOfMethods[sMethodName].type = myType;
}
[parameters_decl(myClass.listOfMethods[sMethodName])]? ')' ';';
parameters_decl(myMethod : node) ::=
parameter(myMethod)
//note: a parameter declaration is expected after the comma,
[',' #continue parameters_decl(myMethod)]*;
parameter(myMethod : node) ::=
[parameter_mode]?:sMode
=> local myType;
type_specifier(myType)
IDENT:sParameterName
=> {
//note: about parsing, parameters are modeled into node
//note: \textbf{myMethod.listOfParameters[}\textit{sParameterName}\textbf{]},
insert myMethod.listOfParameters[sParameterName].name = sParameterName;
setall myMethod.listOfParameters[sParameterName].type = myType;
if sMode {
insert myMethod.listOfParameters[sParameterName].name = sMode;
}
};
parameter_mode ::= IDENT:{"in", "inout", "out"};
type_specifier(myType : node) ::=
basic_type(myType)
//note: about parsing, \textbf{myType.isArray} contains \samp{true} if type is an array,
['[' #continue ']' => insert myType.isArray = true; ]?;
basic_type(myType : node) ::=
//note: about parsing, \textbf{myType.name} contains the name of basic type,
["int" | "boolean" | "double" | "string"]:myType.name
|
class_specifier(myType);
class_specifier(myType : node) ::=
//note: about parsing, \textbf{myType.isAggregation} contains \samp{true} if
//note: the object is aggregated,
["aggregate" => insert myType.isAggregation = true; ]?
//note: about parsing, \textbf{myType.isObject} contains \samp{true} because
//note: this type is a class specifier,
IDENT:myType.name => {insert myType.isObject = true; };
//note: the lexical clause \textit{IDENT} recognizes identifiers and might be replaced by
//note: the predefined clause \samp{\#readIdentifier}, which does the same work,
IDENT ::= #!ignore ['a'..'z'|'A'..'Z'|'_']
['a'..'z'|'A'..'Z'|'_'|'0'..'9']*;

# Covered source code: 83%