1 using System;
2 using MdbTokens;
3
4 parser MdbExprParser
5 {
6 uselexer MdbLexer;
7 main;
8
9 Expression : cmsx.debug.Node*
10 ::= FormatExpression:formatExpr{ return formatExpr; }
11 ;
12
13 FormatExpression(var UniquePtr<cmsx.debug.Node> node) : cmsx.debug.Node*
14 ::= (BinaryExpression:binaryExpr{ node.Reset(binaryExpr); } (DOT Format:f{ node.Reset(new cmsx.debug.FormatExpressionNode(span, node.Release(), f)); })?){ return node.Release(); }
15 ;
16
17 Format(var Span s) : cmsx.debug.ResultFormat
18 ::= ID
19 {
20 pass = true;
21 cmsx.debug.ResultFormat format;
22 string f = ToUtf8(lexer.GetToken(pos).match.ToString());
23 switch (cast<char>(f[0]))
24 {
25 case 'b': format.type = cmsx.debug.Type.byte_; break;
26 case 'w': format.type = cmsx.debug.Type.wyde; break;
27 case 't': format.type = cmsx.debug.Type.tetra; break;
28 case 'o': format.type = cmsx.debug.Type.octa; break;
29 case 'c': format.type = cmsx.debug.Type.char_; break;
30 case 's': format.type = cmsx.debug.Type.string; break;
31 default: pass = false; break;
32 }
33 if (pass == true)
34 {
35 if (f.Length() == 2)
36 {
37 switch (cast<char>(f[1]))
38 {
39 case 's': format.modifier = cmsx.debug.Modifier.signed; break;
40 case 'x': format.modifier = cmsx.debug.Modifier.hex; break;
41 default: pass = false; break;
42 }
43 }
44 else if (f.Length() > 2)
45 {
46 pass = false;
47 }
48 }
49 if (pass)
50 {
51 return format;
52 }
53 }
54 | (DEC{ s = span; } (ID{ s.end = span.end; })?)
55 {
56 pass = true;
57 cmsx.debug.ResultFormat format;
58 string f = ToUtf8(lexer.GetMatch(s));
59 switch (cast<char>(f[0]))
60 {
61 case '1': format.type = cmsx.debug.Type.byte_; break;
62 case '2': format.type = cmsx.debug.Type.wyde; break;
63 case '4': format.type = cmsx.debug.Type.tetra; break;
64 case '8': format.type = cmsx.debug.Type.octa; break;
65 default: pass = false; break;
66 }
67 if (pass == true)
68 {
69 if (f.Length() == 2)
70 {
71 switch (cast<char>(f[1]))
72 {
73 case 's': format.modifier = cmsx.debug.Modifier.signed; break;
74 case 'x': format.modifier = cmsx.debug.Modifier.hex; break;
75 default: pass = false; break;
76 }
77 }
78 else if (f.Length() > 2)
79 {
80 pass = false;
81 }
82 }
83 if (pass)
84 {
85 return format;
86 }
87 }
88 ;
89
90 BinaryExpression(var UniquePtr<cmsx.debug.Node> node) : cmsx.debug.Node*
91 ::= (Term:left{ node.Reset(left); } (WeakOperator:op Term:right{ node.Reset(new cmsx.debug.BinaryExpressionNode(span, node.Release(), right, op)); })*){ return node.Release(); }
92 ;
93
94 WeakOperator : cmsx.debug.Operator
95 ::= PLUS{ return cmsx.debug.Operator.add; }
96 | MINUS{ return cmsx.debug.Operator.sub; }
97 | BAR{ return cmsx.debug.Operator.or_; }
98 | CARET{ return cmsx.debug.Operator.xor_; }
99 ;
100
101 Term(var UniquePtr<cmsx.debug.Node> node) : cmsx.debug.Node*
102 ::= (UnaryExpression:left{ node.Reset(left); } (StrongOperator:op UnaryExpression:right{ node.Reset(new cmsx.debug.BinaryExpressionNode(span, node.Release(), right, op)); })*)
103 {
104 return node.Release();
105 }
106 ;
107
108 StrongOperator : cmsx.debug.Operator
109 ::= AST{ return cmsx.debug.Operator.mul; }
110 | SLASH{ return cmsx.debug.Operator.div; }
111 | PERCENT{ return cmsx.debug.Operator.mod; }
112 | SHIFT_LEFT{ return cmsx.debug.Operator.shiftLeft; }
113 | SHIFT_RIGHT{ return cmsx.debug.Operator.shiftRight; }
114 | AMP{ return cmsx.debug.Operator.and_; }
115 ;
116
117 UnaryExpression : cmsx.debug.Node*
118 ::= LPAREN Expression:expr RPAREN{ return new cmsx.debug.ParenthesizedExpressionNode(span, expr); }
119 | UnaryOperator:op UnaryExpression:child{ return new cmsx.debug.UnaryExpressionNode(span, child, op); }
120 | PrimaryExpression:primary{ return primary; }
121 ;
122
123 UnaryOperator : cmsx.debug.Operator
124 ::= PLUS{ return cmsx.debug.Operator.unaryPlus; }
125 | MINUS{ return cmsx.debug.Operator.unaryMinus; }
126 | TILDE{ return cmsx.debug.Operator.complement; }
127 | AST{ return cmsx.debug.Operator.deref; }
128 ;
129
130 PrimaryExpression : cmsx.debug.Node*
131 ::= SEG
132 {
133 uchar s = lexer.GetToken(pos).match.ToString()[1];
134 switch (s)
135 {
136 case 't': return new cmsx.debug.SegmentNode(span, cmsx.machine.textSegmentIndex);
137 case 'd': return new cmsx.debug.SegmentNode(span, cmsx.machine.dataSegmentIndex);
138 case 'p': return new cmsx.debug.SegmentNode(span, cmsx.machine.poolSegmentIndex);
139 case 's': return new cmsx.debug.SegmentNode(span, cmsx.machine.stackSegmentIndex);
140 case 'k': return new cmsx.debug.SegmentNode(span, cmsx.machine.numSegments);
141 }
142 return null;
143 }
144 | REG
145 {
146 byte x = ParseByte(ToUtf8(lexer.GetToken(pos).match.ToString().Substring(1)));
147 return new cmsx.debug.RegNumberNode(span, x);
148 }
149 | HEX
150 {
151 ulong x = ParseHexULong(ToUtf8(lexer.GetToken(pos).match.ToString().Substring(1)));
152 return new cmsx.debug.HexNumberNode(span, x);
153 }
154 | DEC
155 {
156 ulong x = ParseULong(ToUtf8(lexer.GetToken(pos).match.ToString()));
157 return new cmsx.debug.DecNumberNode(span, x);
158 }
159 | ID
160 {
161 ustring id = lexer.GetToken(pos).match.ToString();
162 return new cmsx.debug.SymbolNode(span, id);
163 }
164 ;
165 }