Updated Application overview (markdown)
@@ -2,7 +2,7 @@
|
||||
[[schemas/architecture.svg]]
|
||||
|
||||
The system is composed of following components (which are technically Gradle subprojects) :
|
||||
* `core` - the SMNP language engine consisting of interpreter (being actually a facade for tokenizer, parser and evaluator), as well as the modules management system
|
||||
* `core` - the SMNP language engine consisting of interpreter (being actually a facade for tokenizer, parser and evaluator), as well as the modules' management system
|
||||
* `app` - the commandline-based frontend for `core` component
|
||||
* modules (`smnp.lang`, `smnp.io`, `smnp.audio.synth` etc.) - a set of external modules that extends the functionality of SMNP scripts
|
||||
* `api` - component that provides shared interfaces and abstract classes common for both `core` and each module components.
|
||||
@@ -149,10 +149,10 @@ parenthesesExpr ::= '(' expr ')' ;
|
||||
atom ::= parenthesesExpr | identifier | staff | list | map ;
|
||||
```
|
||||
|
||||
Therefore `allOf(a, b, c) {...}` is equivalent of `a = a b c`, whereas `oneOf(a, b, c)` is equivalent of `a = a | b | c`.
|
||||
Therefore, `allOf(a, b, c) {...}` is equivalent of `a = a b c`, whereas `oneOf(a, b, c)` is equivalent of `a = a | b | c`.
|
||||
|
||||
### Parsers' cascade
|
||||
Parsers are cascadingly composed and thanks to that, they are able to parse a one-dimensional tokens stream to tree structure. For example, the mentioned before `AtomParser` is used by `UnitParser` which is responsible for parsing minus operator and dot operator. In turn, the `UnitParser` is used by `FactorParser` that is responsible for parsing `not` operator and power operator. The `FactorParser` is used by `TermParser` which is responsible for parsing product operator. The `TermParser` is used by `SubexpressionParser` which provides production rules for logic operators, relation operators etc. The `SubexpressionParser` is used by `ExpressionParser` which technically is `oneOf`-based wrapper for `SubexpressionParser` and `LoopParser`. The `ExpressionParser represents all constructions that can product a value and is used by `StatementParser` which is eventually used by `RootParser`.
|
||||
Parsers are cascaded composed and thanks to that, they are able to parse a one-dimensional tokens' stream to tree structure. For example, the mentioned before `AtomParser` is used by `UnitParser` which is responsible for parsing minus operator and dot operator. In turn, the `UnitParser` is used by `FactorParser` that is responsible for parsing `not` operator and power operator. The `FactorParser` is used by `TermParser` which is responsible for parsing product operator. The `TermParser` is used by `SubexpressionParser` which provides production rules for logic operators, relation operators etc. The `SubexpressionParser` is used by `ExpressionParser` which technically is `oneOf`-based wrapper for `SubexpressionParser` and `LoopParser`. The `ExpressionParser represents all constructions that can product a value and is used by `StatementParser` which is eventually used by `RootParser`.
|
||||
|
||||
The order of each parser in the cascade determines the precedence of each operation and has influence on the
|
||||
AST's shape. Take look at the following example:
|
||||
@@ -194,8 +194,33 @@ class SubexpressionParser : Parser() {
|
||||
return expr4Parser.parse(input)
|
||||
}
|
||||
```
|
||||
This is a code of `SubexpressionParser` and it consists of 4 subparser cascadingly composed. Because of the `expr4Parser` (responsible for `or` operator) is defined using `expr3Parser` (responsible for `and` operator), the `or` operator has a higher precendee than `and` operator (please compare [[Operators#Operators precedence]].
|
||||
Take a look at the following AST:
|
||||
This is a code of `SubexpressionParser` and it consists of 4 subparsers cascaded composed. Because of the `expr4Parser` (responsible for `or` operator) is defined using `expr3Parser` (responsible for `and` operator), the `or` operator has a higher precedence than `and` operator (please compare [[Operators#Operators precedence]]).
|
||||
|
||||
Following listening features the composition of `and` and `or` operator nodes honoring their precedence:
|
||||
```
|
||||
$ smnp --ast --dry-run -c "true and false or not false and not false;"
|
||||
RootNode 1:16
|
||||
└─LogicOperatorNode 1:16
|
||||
├─LogicOperatorNode 1:6
|
||||
│ ├─BoolLiteralNode 1:1
|
||||
│ │ └ (bool, »true«, 1:1)
|
||||
│ ├─TokenNode 1:6
|
||||
│ │ └ (and, »and«, 1:6)
|
||||
│ └─BoolLiteralNode 1:10
|
||||
│ └ (bool, »false«, 1:10)
|
||||
├─TokenNode 1:16
|
||||
│ └ (or, »or«, 1:16)
|
||||
└─LogicOperatorNode 1:29
|
||||
├─NotOperatorNode 1:19
|
||||
│ ├─TokenNode 1:19
|
||||
│ │ └ (not, »not«, 1:19)
|
||||
│ └─BoolLiteralNode 1:23
|
||||
│ └ (bool, »false«, 1:23)
|
||||
├─TokenNode 1:29
|
||||
│ └ (and, »and«, 1:29)
|
||||
└─NotOperatorNode 1:33
|
||||
├─TokenNode 1:33
|
||||
│ └ (not, »not«, 1:33)
|
||||
└─BoolLiteralNode 1:37
|
||||
└ (bool, »false«, 1:37)
|
||||
```
|
||||
Reference in New Issue
Block a user