CxCodeUnit
Description
- Derived from
-
CxNode abstract
ICxFullNameContainer
Represents a Code-X unit:
// Comment using Usings.First; using Usings.Second; ... #pragma ... (ignored) // ... (ignored) namespace Namespace { class Declaration { ... } }
The Tinman 3D SDK is developed and maintained in Code-X, which is a subset of the C# Language Specification Version 7.3 (see https://www.microsoft.com/en-us/download/details.aspx?id=7029), with additional syntactic and semantic rules and concepts (see https://manual.tinman3d.com/STABLE-PREVIEW/software-architecture.html#_code_concepts). The syntax of a Code-X source code unit is defined by the following Grammar:
# := w ; root := code-unit ; !code-unit := comment? usings? (comment-line | pragma-line)* namespace ; !namespace := 'namespace' w+ (id .. '.') '{' decl '}' ; !pragma-line := '#pragma' ~lb* lb ; usings := using using* ; !decl := xmldoc? attribs? modifiers (class | delegate | enum | interface | struct) ; !using := 'using' w+ name ';' ; !class := 'class' w+ name-id type-params? base-types? constraints? regions ; !delegate := 'delegate' w+ var-decl type-params? params constraints? ';' ; !enum := 'enum' w+ name-id '{' (item .. comma) '}' ; !interface := 'interface' w+ name-id type-params? base-types? constraints? regions ; !struct := 'struct' w+ name-id type-params? base-types? constraints? regions ; base-types := ':' (type .. comma) ; item := xmldoc? name-id '=' expr ; regions := '{' region* '}' ; region := '#region' ws ~lb+ lb member* '#endregion' ; member := xmldoc? attribs? modifiers (constant | constructor | field | indexer | method | operator | property) ; !constant := 'const' w+ var-def ';' ; !constructor := name-id params (':' 'base' '(' (expr .. comma)? ')')? stat-block ; !field := var ';' ; !indexer := type 'this' '[' var-decl ']' '{' getter? setter? '}' ; !method := var-decl type-params? params constraints? (stat-block | ';') ; modifiers := ('public' w+)? ('protected' w+)? ('internal' w+)? ('new' w+)? ('abstract' w+)? ('virtual' w+)? ('override' w+)? ('sealed' w+)? ('static' w+)? ('readonly' w+)? ('volatile' w+)? ('partial' w+)? ; !operator := type 'operator' operator-op params stat-block ; !property := var-decl '{' getter? setter? '}' ; !xmldoc := (ws* xmldoc-line)+ ; constraints := constraint constraint* ; getter := 'get' (';' | stat-block) ; operator-op := '==' | '!=' | '>=' | '<=' | '<<' | '>>' | '&' | '/' | '>' | '~' | '<' | '%' | '*' | '-' | '!' | '|' | '+' | '^' ; params := '(' (param .. comma)? ')' ; setter := 'set' (';' | stat-block) ; type-params := '<' (type-param .. comma) '>' ; xmldoc-line := '///' (ws ~lb*)? lb ; constraint := 'where' w+ name-id ':' (constraint-item .. comma)? ; param := attribs? (('ref' | 'out' | 'this') w+)? var ; type-param := (('in' | 'out') w+)? name-id ; attribs := '[' (attrib .. comma) ']' ; constraint-item := 'class' | 'struct' | 'new()' | type-generic ; attrib := name-id ('(' (expr .. comma) ')')? ; !arg := (('out' | 'ref') w+)? expr ; expr := expr-assign ; !expr-add := expr-mul !> (expr-add-op expr-mul)+ ; !expr-assign := expr-cond !> (expr-assign-op expr-cond)+ ; !expr-brace := '(' expr ')' ; !expr-cond := expr-cond-or !> '?' expr-cond ':' expr-cond ; !expr-cond-and := expr-logic-or !> ('&&' expr-logic-or)+ ; !expr-cond-or := expr-cond-and !> ('||' expr-cond-and)+ ; !expr-default := 'default' '(' type ')' ; !expr-equal := expr-relate !> expr-equal-op expr-relate ; !expr-generic := expr-name !> '<' (type .. comma) '>' ; !expr-logic-and := expr-equal !> ('&' expr-equal)+ ; !expr-logic-or := expr-logic-xor !> ('|' expr-logic-xor)+ ; !expr-logic-xor := expr-logic-and !> ('^' expr-logic-and)+ ; !expr-mul := expr-unary !> (expr-mul-op expr-unary)+ ; !expr-new := 'new' w+ type (expr-new-object | expr-new-array1 | expr-new-array2) ; !expr-new-array1 := '{' (expr .. comma)? '}' ; !expr-new-array2 := '[' expr ']' '[]'* ; !expr-new-object := '(' (expr .. comma)? ')' ; !expr-primary := expr-brace | expr-new | expr-literal | expr-default | expr-generic ; !expr-relate := expr-shift !> expr-relate-op expr-shift ; !expr-shift := expr-add !> (expr-shift-op expr-add)+ ; !expr-suffix := expr-primary !> expr-suffix-op+ ; expr-suffix-op := '(' (arg .. comma)? ')' | '.' expr-generic | '[' expr ']' | '++' | '--' ; !expr-unary := expr-unary-op+ <! expr-suffix ; expr-unary-op := '++' | '+' | '--' | '-' \ literal-number | '!' | '~' | '(' type ')' <expr> ; for-cond := expr ; for-next := expr (comma expr)* ; stat := stat-block | stat-debug | stat-do | stat-foreach | stat-for | stat-if | stat-native | stat-return | stat-simple | stat-switch | stat-throw | stat-try | stat-while | stat-variable | stat-expr | stat-comment ; !stat-block := '{' stat* '}' ; !stat-debug := '#if' 'DEBUG' stat* '#endif' ; !stat-do := 'do' stat-block 'while' '(' expr ')' ';' ; stat-expr := expr ';' ; !stat-for := 'for' '(' var-def? ';' for-cond ';' for-next? ')' stat ; !stat-foreach := 'foreach' '(' var-decl 'in' expr ')' stat ; !stat-if := 'if' '(' expr ')' stat ('else' stat)? ; !stat-return := 'return' (w+ expr)? ';' ; !stat-switch := 'switch' '(' expr ')' '{' switch-case* switch-default? '}' ; !stat-throw := 'throw' (w+ expr)? ';' ; !stat-try := 'try' stat-block try-catch? try-finally? ; !stat-variable := var ';' ; !stat-while := 'while' '(' expr ')' stat ; switch-case := 'case' w+ expr ':' stat* ; switch-default := 'default:' stat* ; try-catch := 'catch' '(' type (w+ name-id)? ')' stat-block ; try-finally := 'finally' stat-block ; !type := type-no-array !> '[]'+ ; type-generic := type-name !> '<' (type .. comma) '>' ; type-no-array := type-simple | type-generic ; var := type w+ name-id ('=' expr)? ; var-decl := type w+ name-id ; var-def := type w+ name-id '=' expr ; !expr-literal := literal ; literal := literal-simple | literal-string | literal-char | literal-hex | literal-number ; type-name := name ; !expr-name := id ; !literal-char := '\'' (escape | ]'\\[) '\'' ; !literal-string := '"' (escape | ]"\\[ \ '\\"')* '"' | '@"' ('""' | ]"[)* '"' ; name := 'global::'? (id .. '.') ; name-id := id ; !stat-comment := comment ; !stat-native := '#region' ws 'Native' ws '{' guid '}' lb ~native-end* native-end lb ; comment := comment-line comment-line* ; escape := '\\"' | '\\0' | '\\\'' | '\\\\' | '\\b' | '\\f' | '\\n' | '\\r' | '\\t' | '\\u' hex-digit[4] ; !guid := hex-digit[8] ('-' hex-digit[4])[3] '-' hex-digit[12] ; !id := letter id-char* ; !literal-hex := @'0x' hex-digit+ @'L'? ; !literal-simple := ('null' | 'this' | 'base' | 'true' | 'false') >id-char< ; !type-simple := ('bool' | 'sbyte' | 'char' | 'short' | 'int' | 'long' | 'float' | 'double' | 'string' | 'object' | 'void') >id-char< ; !comment-line := '//' \ '///' ws? ~lb* lb ; hex-digit := dec-digit | 'a'..'f' | 'A'..'F' ; id-char := letter | dec-digit ; !literal-number := '-'? dec-digit+ ('.' dec-digit+)? (@'E' ('-' | '+')? dec-digit+)? [FLfl]? ; native-end := lb ws* '#endregion' ; w := ws | lb ; comma := ',' ; dec-digit := '0'..'9' ; expr-add-op := '+' | '-' ; expr-assign-op := '=' | '*=' | '/=' | '%=' | '+=' | '-=' | '<<=' | '>>=' | '&=' | '^=' | '|=' ; expr-equal-op := '==' | '!=' ; expr-mul-op := '*' | '/' \ '//' | '%' ; expr-relate-op := '<=' | '<' | '>=' | '>' | 'is' | 'as' ; expr-shift-op := '<<' | '>>' ; lb := '\r' '\n'? | '\n' ; letter := 'a'..'z' | 'A'..'Z' | '_' ; !stat-simple := ('break' | 'continue') ';' ; ws := '\t' | ' ' ;
The CxNode class represents a single node of the program structure information (PSI) model of a Code-X unit. To obtain a CxNode from source code, use one of the following parse methods:
-
CxCodeUnit via FromSource using
root
. -
CxDeclaration via CxDeclaration.FromSource using
decl
. -
CxExpression via CxExpression.FromSource using
expr
. -
CxId via CxId.FromSource using
id
. -
CxLiteral via CxLiteral.FromSource using
literal
. -
CxMember via CxMember.FromSource using
member
. -
CxName via CxName.FromSource using
name
. -
CxStatement via CxStatement.FromSource using
stat
. -
CxType via CxType.FromSource using
type
.
Alternatively, a PSI model may be created by instantiating CxNode classes directly. To obtain parsable source code from CxNode objects, use ICodeOutput.WriteSourceCode or - as a shortcut - object.ToString.
Public / Constructors
FromFile
Parses the given Code-X unit.
- ValidatingException
-
If the syntax of file in is invalid.
- IOException
-
If an I/O error has occurred.
FromSource
Parses the given Code-X unit.
- ValidatingException
-
If the syntax of source in is invalid.