我正在使用C#编写PLC语言解释器。我的解释器有自己的类型层次结构:元素类型(整数,布尔值,...)和派生类型(结构,数组,......)。从我的ANTLR语法创建多维数字数组时遇到问题。
这是我的语言声明多维数组(3x2 int数组)的方式:
TYPE
MY_ARRAY : ARRAY [0..2, 1..2] OF INT;
END_TYPE
我的解析一维数组声明的antlr语法是下一个:
decl_derivated
: 'TYPE' NEWLINE* ID ':' NEWLINE* type_decl ';' NEWLINE* 'END_TYPE' NEWLINE* -> ^(TYPEDEF<TypeDefinition>[$ID.text, $type_decl.type])
;
type_decl returns [Type type]
: 'STRUCT' NEWLINE* decl_fields 'END_STRUCT' { $type = new STRUCT($decl_fields.fieldList); }
| 'ARRAY' '[' range ']' 'OF' type_var { $type = new ARRAY($type_var.type, $range.init, $range.end); }
;
range returns [int init, int end]
: ini=CTE_INT '..' en=CTE_INT { $init = int.Parse($ini.text); $end = int.Parse($en.text); }
;
type_var returns [Type type]
: 'BOOL' { $type = new BOOL(); }
| 'INT' { $type = new INT(); }
| 'REAL' { $type = new REAL(); }
;
/* lexer */
ID : (LETTER | '_') (LETTER | DIGIT | '_')*
;
fragment
DIGIT : '0'..'9'
;
fragment
INTEGER : DIGIT ('_'|DIGIT)*
;
fragment
EXPONENT : ('e'|'E') ('+'|'-')? INTEGER ;
fragment
CTE_INT
: ('+'|'-'| ) INTEGER
;
fragment
CTE_REAL
: ('+'|'-'| /*vacio*/ ) INTEGER '.' INTEGER EXPONENT?
;
RANGE : '..' ;
RANGE_OR_INT
: ( CTE_INT RANGE ) => CTE_INT { $type=CTE_INT; }
| ( CTE_REAL ) => CTE_REAL { $type=CTE_REAL; }
| CTE_INT { $type=CTE_INT; }
;
NEWLINE : '\r'? '\n'
| '\r'
;
解析多维数组我没有问题,将数组声明中的语法改为:
type_decl returns [Type type]
: 'ARRAY' '[' range (',' range)* ']' 'OF' type_var
我不知道如何编写这个多维数组的构造函数。 有人可以帮帮我吗? 谢谢。
答案 0 :(得分:1)
<强>解强>
最后,我已经实现了更好,更优雅的解决方案。我在我的ARRAY数据类型类中添加了两个新方法:一个用于添加新维度,另一个用于设置基本类型。
public class ARRAY : ANY_DERIVED
{
public Type de; // ARRAY type
public int size;
public int initIndex;
public int finalIndex;
public ARRAY(int initIndex, int finalIndex)
{
this.initIndex = initIndex;
this.finalIndex = finalIndex;
size = finalIndex - initIndex + 1;
}
public void NewDim(int initIndex, int finalIndex)
{
if (de == null)
de = new ARRAY(initIndex, finalIndex);
else
((ARRAY)de).NewDim(initIndex, finalIndex);
}
public void SetBaseType(Type t)
{
if (de == null)
de = t;
else
((ARRAY)de).SetBaseType(t);
}
}
ANTLR语法:
decl_type returns [Type type]
: 'ARRAY' '[' r1=range {$type = new ARRAY($r1.init, $r1.end);} (',' r2=range {((ARRAY)$type).NewDim($r2.init, $r2.end);})* ']' 'OF' type_var { ((ARRAY)$type).SetBaseType($type_var.type); }
;
无论如何,谢谢你的时间;)