CxCodeUnit
Description
- Derived from
-
CxNode abstract
ICxFullNameContainer
IPathInfo
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 8.0 (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 ; . . !comment := comment-line comment-line* ; . !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 := ('using' w+)? var ';' (ws* '//' ws* '[' ws* ('!' ws*)? ('*' ws*)? ']' ws* lb)? ; . !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 ; . !stat-comment := comment-prefix (comment-tag | ws?) comment-text . (ws* comment-line)* ; . type-name := name ; . . comment-tag := ws* id ':' ws ; . !expr-name := id ; . !literal-char := '\'' (escape | ]'\\[) '\'' ; . !literal-string := '"' (escape | ]"\\[ \ '\\"')* '"' | '@"' ('""' | ]"[)* '"' ; . name := 'global::'? (id .. '.') ; . name-id := id ; . !stat-native := '#region' ws 'Native' ws '{' guid '}' lb ~native-end* native-end . lb ; . . comment-line := comment-prefix ws? comment-text ; . escape := '\\"' | '\\0' | '\\\'' | '\\\\' | '\\b' | '\\f' | '\\n' | '\\r' . | '\\t' | '\\u' hex-digit[4] | '\\U' hex-digit[8] ; . !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-text := ~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 := ',' ; . comment-prefix := '//' \ '///' ; . 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 FromSource1 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
2 overloads
Parses the given Code-X unit, without providing file path information (see IPathInfo.PathInfo).
- ValidatingException
-
If the syntax of file in is invalid.
- IOException
-
If an I/O error has occurred.
Parses the given Code-X unit and provides file path information (see IPathInfo.PathInfo).
- ValidatingException
-
If the syntax of file in is invalid.
- IOException
-
If an I/O error has occurred.
FromSource
2 overloads
Parses the given Code-X unit, without providing file path information (see IPathInfo.PathInfo).
- ValidatingException
-
If the syntax of source in is invalid.
Parses the given Code-X unit and provides file path information (see IPathInfo.PathInfo).
- ValidatingException
-
If the syntax of source in is invalid.