Parses most of C3.

This commit is contained in:
Christoffer Lerno
2019-08-09 22:30:04 +02:00
parent 33770b905d
commit ebce81ad51
38 changed files with 9753 additions and 545 deletions

179
resources/c3.l Normal file
View File

@@ -0,0 +1,179 @@
D [0-9]
UN [_]
L [a-zA-Z_]
AN [a-zA-Z_0-9]
H [a-fA-F0-9]
UA [A-Z_0-9]
DC [a-z]
UC [A-Z]
E [Ee][+-]?{D}+
FS (f|F|l|L)
IS (u|U|l|L)*
%{
#include <stdio.h>
#include "y.tab.h"
void count(void);
void comment(void);
%}
%%
"/*" { comment(); }
"break" { count(); return(BREAK); }
"case" { count(); return(CASE); }
"char" { count(); return(CHAR); }
"const" { count(); return(CONST); }
"continue" { count(); return(CONTINUE); }
"default" { count(); return(DEFAULT); }
"do" { count(); return(DO); }
"double" { count(); return(DOUBLE); }
"else" { count(); return(ELSE); }
"enum" { count(); return(ENUM); }
"float" { count(); return(FLOAT); }
"for" { count(); return(FOR); }
"goto" { count(); return(GOTO); }
"if" { count(); return(IF); }
"int" { count(); return(INT); }
"uint" { count(); return(UINT); }
"long" { count(); return(LONG); }
"ulong" { count(); return(ULONG); }
"return" { count(); return(RETURN); }
"short" { count(); return(SHORT); }
"ushort" { count(); return(USHORT); }
"sizeof" { count(); return(SIZEOF); }
"local" { count(); return(LOCAL); }
"type" { count(); return(TYPE); }
"error" { count(); return(ERROR); }
"module" { count(); return(MODULE); }
"as" { count(); return(AS); }
"import" { count(); return(IMPORT); }
"generic" { count(); return(GENERIC); }
"struct" { count(); return(STRUCT); }
"switch" { count(); return(SWITCH); }
"typedef" { count(); return(TYPEDEF); }
"union" { count(); return(UNION); }
"void" { count(); return(VOID); }
"volatile" { count(); return(VOLATILE); }
"while" { count(); return(WHILE); }
"throw" { count(); return(THROW); }
"throws" { count(); return(THROWS); }
"func" { count(); return(FUNC); }
"nil" { count(); return(NIL); }
"next" { count(); return(NEXT);
[_]*[A-Z]{UA}* { count(); return(CONST_IDENT); }
[_]*[A-Z]{UA}*[a-z]{AN}* { count(); return(TYPE_IDENT); }
[_]*[a-z]{AN}* { count(); return(IDENT); }
@{L}+[!]? { count(); return(AT_IDENT); }
${L}+ { count(); return(CT_IDENT); }
#{L}+ { count(); return(HASH_IDENT); }
0[xX]{H}+{IS}? { count(); return(CONSTANT); }
0{D}+{IS}? { count(); return(CONSTANT); }
{D}+{IS}? { count(); return(CONSTANT); }
L?'(\\.|[^\\'])+' { count(); return(CONSTANT); }
{D}+{E}{FS}? { count(); return(CONSTANT); }
{D}*"."{D}+({E})?{FS}? { count(); return(CONSTANT); }
{D}+"."{D}*({E})?{FS}? { count(); return(CONSTANT); }
L?\"(\\.|[^\\"])*\" { count(); return(STRING_LITERAL); }
"..." { count(); return(ELLIPSIS); }
">>=" { count(); return(RIGHT_ASSIGN); }
"<<=" { count(); return(LEFT_ASSIGN); }
"+=" { count(); return(ADD_ASSIGN); }
"-=" { count(); return(SUB_ASSIGN); }
"*=" { count(); return(MUL_ASSIGN); }
"/=" { count(); return(DIV_ASSIGN); }
"%=" { count(); return(MOD_ASSIGN); }
"&=" { count(); return(AND_ASSIGN); }
"^=" { count(); return(XOR_ASSIGN); }
"|=" { count(); return(OR_ASSIGN); }
">>" { count(); return(RIGHT_OP); }
"<<" { count(); return(LEFT_OP); }
"++" { count(); return(INC_OP); }
"--" { count(); return(DEC_OP); }
"&&" { count(); return(AND_OP); }
"||" { count(); return(OR_OP); }
"<=" { count(); return(LE_OP); }
">=" { count(); return(GE_OP); }
"==" { count(); return(EQ_OP); }
"!=" { count(); return(NE_OP); }
"::" { count(); return(SCOPE); }
"?:" { count(); return(ELVIS); }
";" { count(); return(';'); }
("{") { count(); return('{'); }
("}") { count(); return('}'); }
"," { count(); return(','); }
":" { count(); return(':'); }
"=" { count(); return('='); }
"(" { count(); return('('); }
")" { count(); return(')'); }
("[") { count(); return('['); }
("]") { count(); return(']'); }
"." { count(); return('.'); }
"&" { count(); return('&'); }
"!" { count(); return('!'); }
"~" { count(); return('~'); }
"-" { count(); return('-'); }
"+" { count(); return('+'); }
"*" { count(); return('*'); }
"/" { count(); return('/'); }
"%" { count(); return('%'); }
"<" { count(); return('<'); }
">" { count(); return('>'); }
"^" { count(); return('^'); }
"|" { count(); return('|'); }
"?" { count(); return('?'); }
[ \t\v\n\f] { count(); }
. { /* ignore bad characters */ }
%%
int yywrap(void)
{
return 1;
}
void comment(void)
{
char c, c1;
loop:
while ((c = input()) != '*' && c != 0)
putchar(c);
if ((c1 = input()) != '/' && c != 0)
{
unput(c1);
goto loop;
}
if (c != 0)
putchar(c1);
}
int column = 0;
void count(void)
{
int i;
for (i = 0; yytext[i] != '\0'; i++)
if (yytext[i] == '\n')
column = 0;
else if (yytext[i] == '\t')
column += 8 - (column % 8);
else
column++;
ECHO;
}

697
resources/grammar.y Normal file
View File

@@ -0,0 +1,697 @@
%{
#include <stdio.h>
#define YYERROR_VERBOSE
extern char yytext[];
extern int column;
int yylex(void);
void yyerror(char *s);
%}
%token IDENT AT_IDENT CT_IDENT CONSTANT CONST_IDENT TYPE_IDENT STRING_LITERAL SIZEOF
%token INC_OP DEC_OP LEFT_OP RIGHT_OP LE_OP GE_OP EQ_OP NE_OP
%token AND_OP OR_OP MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN
%token SUB_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN
%token XOR_ASSIGN OR_ASSIGN VAR NIL ELVIS HASH_IDENT NEXT
%token TYPEDEF MODULE IMPORT
%token CHAR SHORT INT LONG FLOAT DOUBLE CONST VOLATILE VOID
%token BYTE USHORT UINT ULONG BOOL
%token STRUCT UNION ENUM ELLIPSIS AS LOCAL
%token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN
%token TYPE FUNC ERROR MACRO GENERIC CTIF CTELIF CTENDIF CTELSE CTSWITCH CTCASE CTDEFAULT CTEACH
%token THROWS THROW TRY CATCH SCOPE PUBLIC DEFER ATTRIBUTE
%start translation_unit
%%
ident_scope
: IDENT SCOPE
;
ident_expression
: CONST_IDENT
| IDENT
| CT_IDENT
| AT_IDENT
;
primary_expression
: STRING_LITERAL
| CONSTANT
| NIL
| ident_scope ident_expression
| ident_expression
| base_type initializer_list
| base_type '.' IDENT
| TYPE '(' type_expression ')'
| '(' expression ')'
;
postfix_expression
: primary_expression
| postfix_expression '[' expression ']'
| postfix_expression '(' ')'
| postfix_expression '(' argument_expression_list ')'
| postfix_expression '.' IDENT
| postfix_expression INC_OP
| postfix_expression DEC_OP
;
argument_expression_list
: expression
| argument_expression_list ',' expression
;
unary_expression
: postfix_expression
| INC_OP unary_expression
| DEC_OP unary_expression
| unary_operator unary_expression
| SIZEOF '(' type_expression ')'
;
unary_operator
: '&'
| '*'
| '+'
| '-'
| '~'
| '!'
;
multiplicative_expression
: unary_expression
| multiplicative_expression '*' unary_expression
| multiplicative_expression '/' unary_expression
| multiplicative_expression '%' unary_expression
;
shift_expression
: multiplicative_expression
| shift_expression LEFT_OP multiplicative_expression
| shift_expression RIGHT_OP multiplicative_expression
;
bit_expression
: shift_expression
| bit_expression '&' shift_expression
| bit_expression '^' shift_expression
| bit_expression '|' shift_expression
;
additive_expression
: bit_expression
| additive_expression '+' bit_expression
| additive_expression '-' bit_expression
;
relational_expression
: additive_expression
| relational_expression '<' additive_expression
| relational_expression '>' additive_expression
| relational_expression LE_OP additive_expression
| relational_expression GE_OP additive_expression
| relational_expression EQ_OP additive_expression
| relational_expression NE_OP additive_expression
;
logical_expression
: relational_expression
| logical_expression AND_OP relational_expression
| logical_expression OR_OP relational_expression
;
conditional_expression
: logical_expression
| logical_expression '?' expression ':' conditional_expression
| logical_expression ELVIS conditional_expression
;
assignment_expression
: conditional_expression
| unary_expression assignment_operator assignment_expression
| unary_expression '=' initializer_list
;
expression
: assignment_expression
| TRY assignment_expression
| TRY assignment_expression ELSE assignment_expression
;
assignment_operator
: '='
| MUL_ASSIGN
| DIV_ASSIGN
| MOD_ASSIGN
| ADD_ASSIGN
| SUB_ASSIGN
| LEFT_ASSIGN
| RIGHT_ASSIGN
| AND_ASSIGN
| XOR_ASSIGN
| OR_ASSIGN
;
constant_expression
: conditional_expression
;
enumerators
: enumerator
| enumerators ',' enumerator
;
enumerator_list
: enumerators
| enumerators ','
;
enumerator
: CONST_IDENT
| CONST_IDENT '=' constant_expression
;
identifier_list
: IDENT
| identifier_list ',' IDENT
;
macro_argument
: CT_IDENT
| IDENT
;
macro_argument_list
: macro_argument
| macro_argument_list ',' macro_argument
;
implicit_decl
: IDENT
| IDENT '=' initializer
;
explicit_decl
: type_expression IDENT '=' initializer
| type_expression IDENT
;
declaration
: explicit_decl
| explicit_decl ',' implicit_decl
| explicit_decl ',' explicit_decl
;
declaration_list
: declaration
;
param_declaration
: type_expression
| type_expression IDENT
| type_expression IDENT '=' initializer
;
parameter_type_list
: parameter_list
| parameter_list ',' ELLIPSIS
| parameter_list ',' type_expression ELLIPSIS
;
opt_parameter_type_list
: '(' ')'
| '(' parameter_type_list ')'
;
parameter_list
: param_declaration
| parameter_list ',' param_declaration
;
base_type
: VOID
| BOOL
| CHAR
| BYTE
| SHORT
| USHORT
| INT
| UINT
| LONG
| ULONG
| FLOAT
| DOUBLE
| TYPE_IDENT
| ident_scope TYPE_IDENT
| TYPE '(' constant_expression ')'
;
type_expression
: base_type
| type_expression '*'
| type_expression '&'
| type_expression '[' constant_expression ']'
| type_expression '[' ']'
| type_expression '[' '+' ']'
;
initializer
: expression
| initializer_list
;
initializer_values
: initializer
| initializer_values ',' initializer
;
initializer_list
: '{' initializer_values '}'
| '{' initializer_values ',' '}'
;
ct_case_statement
: CTCASE type_list ':' statement
| CTDEFAULT ':' statement
;
ct_elif_body
: ct_elif compound_statement
| ct_elif_body ct_elif compound_statement
;
ct_else_body
: ct_elif_body
| CTELSE compound_statement
| ct_elif_body CTELSE compound_statement
;
ct_switch_body
: ct_case_statement
| ct_switch_body ct_case_statement
;
ct_statement
: ct_if compound_statement
| ct_if compound_statement ct_else_body
| ct_switch '{' ct_switch_body '}'
| CTEACH '(' expression AS CT_IDENT ')' statement
;
throw_statement
: THROW expression ';'
statement
: compound_statement
| labeled_statement
| expression_statement
| selection_statement
| iteration_statement
| jump_statement
| declaration_statement
| volatile_statement
| catch_statement
| try_statement
| defer_statement
| ct_statement
| throw_statement
;
defer_catch_body
: compound_statement
| expression_statement
| jump_statement
| iteration_statement
| selection_statement
;
defer_statement
: DEFER defer_catch_body
| DEFER catch_statement
;
catch_statement
: CATCH '(' type_expression IDENT ')' defer_catch_body
| CATCH '(' ERROR IDENT ')' defer_catch_body
;
try_statement
: TRY selection_statement
| TRY iteration_statement
| TRY jump_statement
;
volatile_statement
: VOLATILE compound_statement
;
label_statement
: IDENT ':' statement
labeled_statement
: label_statement
| CASE constant_expression ':'
| DEFAULT ':'
;
compound_statement
: '{' '}'
| '{' statement_list '}'
;
statement_list
: statement
| statement_list statement
;
declaration_statement
: declaration ';'
;
expression_statement
: ';'
| expression ';'
;
control_expression
: decl_or_expr_list
| declaration_list ';' decl_or_expr_list
;
selection_statement
: IF '(' control_expression ')' statement
| IF '(' control_expression ')' compound_statement ELSE statement
| SWITCH '(' control_expression ')' compound_statement
;
expression_list
: expression
| expression_list ',' expression
;
decl_or_expr_list
: expression_list
| declaration_list
;
for_statement
: FOR '(' decl_or_expr_list ';' expression_statement ')' statement
| FOR '(' decl_or_expr_list ';' expression_statement expression_list ')' statement
;
iteration_statement
: WHILE '(' control_expression ')' statement
| DO statement WHILE '(' expression ')' ';'
| for_statement
;
jump_statement
: GOTO CONSTANT ';'
| CONTINUE ';'
| BREAK ';'
| RETURN ';'
| RETURN expression ';'
;
attribute
: AT_IDENT
| IDENT SCOPE AT_IDENT
| AT_IDENT '(' constant_expression ')'
| IDENT SCOPE AT_IDENT '(' constant_expression ')'
;
attribute_list
: attribute
| attribute_list attribute
;
opt_attributes
: attribute_list
|
;
error_type
: IDENT SCOPE TYPE_IDENT
| TYPE_IDENT
| ERROR '(' expression ')'
;
error_list
: error_type
| error_list error_type
;
throw_declaration
: THROWS
| THROWS error_list
;
opt_throw_declaration
: throw_declaration
|
;
func_name
: IDENT SCOPE TYPE_IDENT '.' IDENT
| TYPE_IDENT '.' IDENT
| IDENT
;
func_declaration
: FUNC type_expression func_name opt_parameter_type_list opt_attributes opt_throw_declaration
;
func_definition
: func_declaration compound_statement
| func_declaration ';'
;
macro_declaration
: MACRO AT_IDENT '(' macro_argument_list ')' compound_statement
;
struct_or_union
: STRUCT
| UNION
;
struct_declaration
: struct_or_union TYPE_IDENT opt_attributes struct_body
;
struct_body
: '{' struct_declaration_list '}'
;
struct_declaration_list
: struct_member_declaration
| struct_declaration_list struct_member_declaration
;
struct_member_declaration
: type_expression identifier_list opt_attributes ';'
| struct_or_union IDENT opt_attributes struct_body
| struct_or_union opt_attributes struct_body
;
enum_declaration
: ENUM TYPE_IDENT ':' type_expression opt_attributes '{' enumerator_list '}'
| ENUM TYPE_IDENT opt_attributes '{' enumerator_list '}'
;
errors
: CONST_IDENT
| errors ',' CONST_IDENT
;
error_list
: errors
| errors ','
;
error_declaration
: ERROR TYPE_IDENT '{' error_list '}'
;
type_list
: type_expression
| type_list ',' type_expression
;
generics_case
: CASE type_list ':' statement
generics_body
: generics_case
| generics_body generics_case
;
generics_declaration
: GENERIC IDENT '(' macro_argument_list ')' '{' generics_body '}'
| GENERIC type_expression IDENT '(' macro_argument_list ')' '{' generics_body '}'
;
const_declaration
: CONST CT_IDENT '=' initializer ';'
| CONST type_expression IDENT '=' initializer ';'
;
func_typedef
: FUNC type_expression opt_parameter_type_list opt_throw_declaration
;
typedef_declaration
: TYPEDEF type_expression AS TYPE_IDENT ';'
| TYPEDEF func_typedef AS TYPE_IDENT ';'
;
attribute_domain
: FUNC
| VAR
| ENUM
| STRUCT
| UNION
| TYPEDEF
| CONST
;
attribute_domains
: attribute_domain
| attribute_domains ',' attribute_domain
;
attribute_declaration
: ATTRIBUTE AT_IDENT attribute_domains
| ATTRIBUTE AT_IDENT attribute_domains '(' parameter_type_list ')'
;
global_declaration
: type_expression IDENT ';'
| type_expression IDENT '=' initializer ';'
;
ct_if
: CTIF '(' expression ')'
;
ct_elif
: CTELIF '(' expression ')'
;
ct_switch
: CTSWITCH '(' expression ')'
;
top_level_block
: '{' top_level_statements '}'
;
tl_ct_elif_body
: ct_elif top_level_block
| tl_ct_elif_body ct_elif top_level_block
;
tl_ct_else_body
: tl_ct_elif_body
| tl_ct_else_body CTELSE top_level_block
;
tl_ct_case
: CTCASE type_list ':' top_level_statements
| CTDEFAULT ':' top_level_statements
;
tl_ct_switch_body
: tl_ct_case
| tl_ct_switch_body tl_ct_case
;
conditional_compilation
: ct_if top_level_block
| ct_if top_level_block tl_ct_else_body
| ct_switch '{' tl_ct_switch_body '}'
;
module_param
: CT_IDENT
| HASH_IDENT
| TYPE_IDENT
| AT_IDENT
;
module_params
: module_param
| module_params ',' module_param
;
module
: MODULE IDENT ';'
| MODULE IDENT '(' module_params ')' ';'
;
import_decl
: IMPORT IDENT ';'
| IMPORT IDENT AS IDENT ';'
| IMPORT IDENT AS IDENT LOCAL ';'
| IMPORT IDENT LOCAL ';'
;
imports
: import_decl
| imports import_decl
;
translation_unit
: module imports top_level_statements
;
top_level_statements
: visibility top_level
| top_level_statements visibility top_level
;
visibility
: LOCAL
| PUBLIC
| LOCAL PUBLIC
| PUBLIC LOCAL
|
;
top_level
: func_definition
| conditional_compilation
| struct_declaration
| attribute_declaration
| enum_declaration
| error_declaration
| const_declaration
| global_declaration
| macro_declaration
| generics_declaration
| typedef_declaration
;
%%
void yyerror(char *s)
{
fflush(stdout);
printf("\n%*s\n%*s\n", column, "^", column, s);
}
int main(int argc, char *argv[])
{
yyparse();
return(0);
}

View File

@@ -0,0 +1,11 @@
module foo;
func void test()
{
return;
}
func int test2()
{
return;
}

View File

@@ -0,0 +1,209 @@
module foo ($foo, #bar, Integer);
import bar as eok local;
import bar2 as eok2;
import bar3 local;
macro void @foo(int i, $e)
{
$e = 1;
printf("Helo");
}
macro @goo(i, $e)
{
}
macro @soom!(i, $e)
{}
local struct Foom
{
int i;
Foom *test;
int*** j;
int*[][]* k;
}
struct Hej
{
int x;
}
enum FEok : int {
IFEJ
}
enum Test
{
FOO = 1 + 2,
BAR,
}
enum Test2 : int
{
FOO = 1,
BAR,
}
union Foomt
{
int i;
double d;
}
error Errors
{
BADERROR,
OTHER_ERROR
}
func Foom test(int a)
{
return 1 + 2;
}
func boo::Bar zab::Baz.sd(die::Eij i) throws Zab // , sij:Zig
{
float a = 0, b = 3, double c = 1, d;
int i = 0;
}
generic int boor(i)
{
case int:
return 1;
case double:
return 100;
default:
return 1000;
}
generic boor2(i)
{
case int:
return "Helo";
default:
return 1000;
}
$if ($e > 0)
{
func void foo() {}
}
$elif ($e < 0)
{
func void foo() { printf("HELO"); }
}
$else
{
func void foo() { printf("OLEH"); }
}
$if ($e > 0)
{
func void foo() {}
}
$if ($b > 0)
{
}
$else
{
generic test(i) { }
}
generic boofer2(i, g, eok)
{
case int, char[], type($eoo):
return "Helo";
default:
return 1000;
}
func void hello() throws Errors
{
int i, j;
throw FOO;
throw awesome::FOO;
defer close(b);
foo::Bar x = 3;
try foo();
try foo() else 1;
foo(try 1);
type($error) fk;
type(int).size + fk;
Errors {};
Ferrors{a = 1, b = 20, b = { token }};
Ferrors{1, 3, 1+4};
$erro = 1;
FOO:
goto FOO;
type($error) fk;
foo::@macrof();
int i = foo ? 2 : 4;
@macros();
type(foo::y) z;
type(int) * 2;
$error = type(int);
int[4] a;
foo[1 + 2] * b;
type((i > 0) ? type(int) : type(double)) doek;
$e = type(type(type(Bar)));
$e = foo ? type(int) : type(Bar);
$e = type(type(foo::$eofk));
if (a == 0 && 1 == b)
{
i = 0;
}
while (bpb >= 3)
{
a();
}
do
{
} while (0);
for (i = 0;;)
{}
for (i = 0, j = 3; i < 0; i++, j++) {}
for (int i = 0; i < 100; i++)
{
i++;
}
int i = 1;
i + 1 * 100;
&i;
int j = i;
2;
i++;
switch (int foo = 1; bar)
{
case 1:
next;
continue;
default:
break;
}
do {
i++;
} while (a < 0);
while (a > 0)
{
a--;
}
while (int a = 4; int b = 20)
{
a + 1;
}
return;
}
typedef Foo* as Bar;
typedef func void(int, Foo*) as Zoo;
func void test2()
{
return;
}