177 lines
4.0 KiB
Markdown
177 lines
4.0 KiB
Markdown
# SCC
|
|
|
|
Simple Compiler-Compiler. This program is designed to generate a parser that builds a syntax tree using a rule file with `slex` lexer.
|
|
|
|
Currently, this project aims on supporting following target platform/languages:
|
|
|
|
|Language| Version| Platform|
|
|
|--------|--------|--------- |
|
|
|C | 99 | Win32, POSIX, ESP32 |
|
|
|C# | 9.0 | .netstandard2.1(all possible target platform, including Unity)|
|
|
|
|
## SCC Rule format
|
|
|
|
```
|
|
syntax_ids:
|
|
<id0>
|
|
<id1>
|
|
...
|
|
|
|
rules:
|
|
|
|
node_type
|
|
: [node_type/slex_id/slex_tag/direct_string] [node_type/slex_id/slex_tag/direct_string] ...
|
|
=> [operation] $0 $1 ...
|
|
: [node_type/slex_id/slex_tag/direct_string] [node_type/slex_id/slex_tag/direct_string] ...
|
|
=> [operation] $0 $1 ...
|
|
;
|
|
|
|
#
|
|
# $0 and $1 here means selected node/segment from matching element list.
|
|
#
|
|
|
|
```
|
|
|
|
|
|
### Operations
|
|
|
|
- `new_node <syntax-id>`: create a new node and attach to parent node
|
|
- `append_as_child`: append selected
|
|
- `skip`: do nothing
|
|
|
|
### Sample:
|
|
|
|
```
|
|
|
|
syntax_ids:
|
|
|
|
binary_expr
|
|
function_call_expr
|
|
argument_list
|
|
variable
|
|
|
|
rules:
|
|
|
|
expr
|
|
: expr binary_operator expr
|
|
=> new_node binary_expr $0 $1 $2
|
|
: name "(" argument_list ")"
|
|
=> new_node function_call_expr $0
|
|
| name
|
|
=> new_node variable $0
|
|
;
|
|
|
|
argument_list
|
|
:argument_list "," expr
|
|
=> append_as_child $2
|
|
:expr
|
|
=> new_node argument_list $0
|
|
;
|
|
```
|
|
|
|
## Usage
|
|
|
|
```
|
|
scc [options] <input_file> [options]
|
|
|
|
input file usually ends with `.scc`
|
|
|
|
Options:
|
|
|
|
-o <output> output file/output folder
|
|
-l <language> specify target language, e.g: c, c#, csharp
|
|
-h <header> output header file (will separate output implementation and definitions when language is c or c++. Note: c++ is currently not supported.)
|
|
-ns <namespace> specify namespace (supported languages only). Default is `scc_generated`, `SCCGenerated`, `io.creeperlv.scc.generated` for applicable language.
|
|
-class <class_name> specify class name (supported languages only). Default is `scc`, `SCC`.
|
|
-prefix <function_prefix> specify prefix for functions. Default is `scc_` for languages does not support namespace/class, `` (empty string) for languages support namespace/class.
|
|
-data_type <data_type_name> specify the name of the syntax node data type.
|
|
-slex-ns <namespace> specify namespace used in slex.
|
|
-slex-class <class_name> specify class name used in slex.
|
|
-slex-prefix <function_prefix> specify function prefix used in slex.
|
|
-slex-data_type <data_type_name> specify segment data type used in slex.
|
|
```
|
|
|
|
### Data Type Name Table
|
|
|
|
|Language | Type Name |
|
|
| ------- | ---------------- |
|
|
| C | scc_syntax_node |
|
|
| C# | SyntaxNode |
|
|
|
|
### Generated parser
|
|
|
|
All usages here uses default settings
|
|
|
|
#### C99
|
|
|
|
|
|
Usage sample:
|
|
```
|
|
void scc_sample(FILE* f, char* file_name){
|
|
|
|
struct slex_segment* head;
|
|
const char* str="<some_inputs>";
|
|
if(slex_file(f, file_name, &head)){
|
|
//Success
|
|
struct scc_syntax_node* root;
|
|
if(scc_parse(head,&root)){
|
|
//Success
|
|
}
|
|
}
|
|
slex_free(head);
|
|
}
|
|
```
|
|
|
|
API and defined data types:
|
|
```c
|
|
typedef struct scc_syntax_node_enclosure{
|
|
enum scc_syntax_node_type;
|
|
void* data;
|
|
}scc_syntax_node_enclosure;
|
|
typedef enum scc_syntax_node_type{
|
|
scc_node, scc_segment
|
|
}scc_syntax_node_type;
|
|
typedef struct scc_syntax_node{
|
|
enum scc_syntax_id;
|
|
char* syntax_name;
|
|
scc_syntax_node_enclosure* children;
|
|
uint64_t child_count;
|
|
scc_syntax_node* parent;
|
|
} scc_syntax_node;
|
|
|
|
typedef enum scc_syntax_id{
|
|
default,<generated from rule file>
|
|
}scc_syntax_id;
|
|
char scc_parse(slex_segment* head, scc_syntax_node** output);
|
|
char scc_free(scc_syntax_node* root);
|
|
```
|
|
|
|
#### C#
|
|
##### APIs:
|
|
```
|
|
using SLexGenerated;
|
|
namesapce SCCGenerated{
|
|
public class SCC{
|
|
public bool Parse(Segment head, out SyntaxNode Root);
|
|
}
|
|
|
|
public enum SyntaxId{
|
|
Default,<Generated-from-rule-file>
|
|
}
|
|
public class SyntaxNodeEnclosure{
|
|
public SyntaxNode? Node;
|
|
public Segment? Segment;
|
|
public EnclosureType EnclosureType;
|
|
}
|
|
public enum EnclosureType{
|
|
Node, Segment
|
|
}
|
|
public class SyntaxNode{
|
|
public SyntaxNode? Parent;
|
|
public string SyntaxName;
|
|
public SyntaxId Id;
|
|
public List<SyntaxNodeEnclosure> Children;
|
|
}
|
|
}
|
|
```
|