Files
scc/README.md
T
2026-05-26 19:17:15 +10:00

178 lines
4.1 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-h <header> specify header file slex generated.
-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;
}
}
```