1 module pry.grammar.ast;
2 
3 import std.uni;
4 
5 struct Modifier {
6 	uint min = 1;
7 	uint max = 1;
8 }
9 
10 class Ast {
11 	Modifier mod;
12 	bool ignored;
13 
14 	abstract void accept(Visitor visitor);
15 }
16 
17 abstract class Visitor {
18 	void visit(Grammar grammar);
19 	void visit(Definition def);
20 	void visit(Sequence seq);
21 	void visit(Alternative alt);
22 	void visit(Map map);
23 	void visit(NegativeLookahead neg);
24 	void visit(PositiveLookahead pos);
25 	void visit(SimpleSequence seq);
26 	void visit(CharClass charClass);
27 	void visit(Literal literal);
28 	void visit(Reference refernce);
29 	void visit(Combinator combinator);
30 }
31 
32 mixin template Visitable() {
33 	override void accept(Visitor visitor){
34 		visitor.visit(this);
35 	}
36 }
37 
38 class Grammar : Ast {
39 	string name;
40 	Definition[] defs;
41 
42 	this(string name, Definition[] defs) {
43 		this.name = name;
44 		this.defs = defs;
45 	}
46 	mixin Visitable;
47 }
48 
49 class Definition : Ast {
50 	string name;
51 	string type;
52 	Ast ast;
53   	bool dynamic; // if should be codegened as dynamic!T
54 
55 	this(string name, string type, Ast ast)
56 	{
57 		this.name = name;
58 		this.type = type;
59 		this.ast = ast;
60 	}
61 	mixin Visitable;
62 }
63 
64 class Sequence : Ast {
65 	Ast[] seq;
66 
67 	this(Ast[] sequence){ seq = sequence; }
68 	mixin Visitable;
69 }
70 
71 class Alternative : Ast {
72 	Sequence[] alt;
73 
74 	this(Sequence[] alternatives){ alt = alternatives; }
75 	mixin Visitable;
76 }
77 
78 class Map : Ast {
79 	Ast ast;
80 	string code;
81 
82 	this(Ast subject, string mapper){
83 		ast = subject;
84 		code = mapper;
85 	}
86 	mixin Visitable;
87 }
88 
89 class NegativeLookahead : Ast {
90 	Ast ast;
91 
92 	this(Ast ast){ this.ast = ast; }
93 	mixin Visitable;
94 }
95 
96 class PositiveLookahead : Ast {
97 	Ast ast;
98 
99 	this(Ast ast){ this.ast = ast; }
100 	mixin Visitable;
101 }
102 
103 // A sequence that consits only of char classes and literals
104 // constructed implicitly 
105 class SimpleSequence : Ast {
106 	Ast[] seq;
107 
108 	this(Ast[] sequence){ seq = sequence; }
109 	mixin Visitable;
110 }
111 
112 class Reference : Ast {
113 	string name;
114 
115 	this(string name){ this.name = name; }
116 	mixin Visitable;
117 }
118 
119 class CharClass : Ast {
120 	CodepointSet set;
121 
122 	this(CodepointSet charset){ set = charset; }
123 	mixin Visitable;
124 }
125 
126 class Literal : Ast {
127 	string lit;
128 
129 	this(string literal){ lit = literal; }
130 	mixin Visitable;
131 }
132 
133 class Combinator : Ast {
134 	string combinator;
135 	Ast[] args;
136 
137 	this(string combinator, Ast[] args) {
138 		this.combinator = combinator;
139 		this.args = args;
140 	}
141 	mixin Visitable;
142 }
143