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 }