Commits

Jesse McGrew  committed 08c6e18

Created folders for Tree and Token classes
Renamed Rellor assembly to Rellor.Core

  • Participants
  • Parent commits e2f5505

Comments (0)

Files changed (30)

File Rellor.Core/Inform6.g3

+grammar Inform6;
+
+options
+{
+    language = CSharp3;
+    output = AST;
+    TokenLabelType = RellorToken;
+    ASTLabelType = CommonTree;
+}
+
+tokens {
+    // emitted by lexer
+    CHAR_LITERAL;
+    ARROW='->';
+    DARROW='-->';
+    COMMA=',';
+    NOT='~';
+    LSQUARE='[';
+    RSQUARE=']';
+    SEMI=';';
+    EQ='=';
+	LT='<';
+	GT='>';
+	LTE='<=';
+	GTE='>=';
+	EQEQ='==';
+	NOTEQ='~=';
+	BITAND='&';
+	BITOR='|';
+	LOGAND='&&';
+	LOGOR='||';
+	LOGNOT='~~';
+    STAR='*';
+    SLASH='/';
+	PLUS='+';
+	MINUS='-';
+	PERCENT='%';
+	DOT='.';
+	DOTDOT='..';
+	SUPERCLASS='::';
+	HASH='#';
+	HASHHASH='##';
+	LPAREN='(';
+	RPAREN=')';
+	LBRACE='{';
+	RBRACE='}';
+	PROPADDR='.&';
+	PROPLEN='.#';
+	IPROPADDR='..&';
+	IPROPLEN='..#';
+	INC='++';
+	DEC='--';
+	COLON=':';
+	QUESTION='?';
+	AT='@';
+
+    // emitted by parser
+    INT;
+    UMINUS;
+    OMITTED;
+    INVOKE_ACTION;
+    INVOKE_ACTION_RET;
+    PREINC;
+    POSTINC;
+    PREDEC;
+    POSTDEC;
+    PRINT_AS;
+    FUNCTION_CALL;
+    DEPTH;
+    SHORT_NAME;
+    PARENT;
+    LOCALS;
+    FLAGS;
+    LABEL;
+    ROUTINE;
+    UNINITIALIZED;
+	OLD_OBJECTLOOP;
+	BLOCK;
+	CASE;
+
+    OBJECT;
+    NEARBY;
+    CLASS;
+    WITH;
+    VERB;
+    PRINT;
+    PRINT_RET;
+    IF;
+    WHILE;
+    DO;
+    FOR;
+    OBJECTLOOP;
+    NEAR;
+    FROM;
+    IN;
+    TO;
+    HAS;
+    HASNT;
+    IN;
+    NOTIN;
+    PROVIDES;
+    OFCLASS;
+    OR;
+    BOX;
+    BREAK;
+    CONTINUE;
+    DEFAULT;
+    ELSE;
+    FONT;
+    GIVE;
+    INVERSION;
+    JUMP;
+    MOVE;
+    NEW_LINE;
+    QUIT;
+    READ;
+    REMOVE;
+    RESTORE;
+    RETURN;
+    RFALSE;
+    RTRUE;
+    SAVE;
+    SPACES;
+    STRING;
+    STYLE;
+    SWITCH;
+    UNTIL;
+    ALIAS;
+    LONG;
+    ADDITIVE;
+    SCORE;
+    TIME;
+    NOUN;
+    HELD;
+    MULTI;
+    MULTIHELD;
+    MULTIEXCEPT;
+    MULTIINSIDE;
+    CREATURE;
+    SPECIAL;
+    NUMBER;
+    SCOPE;
+    TOPIC;
+    REVERSE;
+    META;
+    ONLY;
+    REPLACE;
+    FIRST;
+    LAST;
+    TABLE;
+    BUFFER;
+    DATA;
+    INITIAL;
+    INITSTR;
+    PRIVATE;
+    ERROR;
+    FATALERROR;
+    WARNING;
+    TERMINATING;
+    DICTIONARY;
+    SYMBOLS;
+    OBJECTS;
+    VERBS;
+    ASSEMBLY;
+    EXPRESSIONS;
+    LINES;
+    TOKENS;
+    LINKER;
+    ON;
+    OFF;
+    ABBREVIATE;
+    ARRAY;
+    ATTRIBUTE;
+    CONSTANT;
+    END;
+    ENDIF;
+    EXTEND;
+    FAKE_ACTION;
+    GLOBAL;
+    IFDEF;
+    IFNDEF;
+    IFNOT;
+    IFV3;
+    IFV5;
+    IFTRUE;
+    IFFALSE;
+    IMPORT;
+    INCLUDE;
+    LINK;
+    LOWSTRING;
+    MESSAGE;
+    PROPERTY;
+    RELEASE;
+    SERIAL;
+    SWITCHES;
+    STATUSLINE;
+    STUB;
+    SYSTEM_FILE;
+    TRACE;
+    VERSION;
+    ZCHARACTER;
+    CHAR;
+    NAME;
+    THE;
+    A;
+    AN;
+    ROMAN;
+    BOLD;
+    UNDERLINE;
+    FIXED;
+    ADDRESS;
+
+    // synthesized by tree parser later
+    COMMON_METHOD_CALL;
+    COMMON_PROP_ASSIGN;
+    COMMON_PROP_PREINC;
+    COMMON_PROP_PREDEC;
+    COMMON_PROP_POSTINC;
+    COMMON_PROP_POSTDEC;
+    INDIV_METHOD_CALL;
+    INDIV_PROP_ASSIGN;
+    INDIV_PROP_PREINC;
+    INDIV_PROP_PREDEC;
+    INDIV_PROP_POSTINC;
+    INDIV_PROP_POSTDEC;
+    BYTE_ARRAY_ASSIGN;
+    BYTE_ARRAY_PREINC;
+    BYTE_ARRAY_PREDEC;
+    BYTE_ARRAY_POSTINC;
+    BYTE_ARRAY_POSTDEC;
+    WORD_ARRAY_ASSIGN;
+    WORD_ARRAY_PREINC;
+    WORD_ARRAY_PREDEC;
+    WORD_ARRAY_POSTINC;
+    WORD_ARRAY_POSTDEC;
+}
+
+scope Quirks {
+    bool no_func_calls;
+    bool no_byte_deref;
+    bool no_superclass;
+    bool ambiguous_minus;
+}
+
+scope Symbols {
+    IScope scope;
+}
+
+@lexer::header {
+using Rellor.Core.Token;
+
+// 'class' does not need a CLSCompliant attribute because the assembly does not have a CLSCompliant attribute
+#pragma warning disable 3021
+}
+
+@parser::header {
+using System;
+using Rellor.Core.Token;
+using Rellor.Core.Tree;
+
+// 'class' does not need a CLSCompliant attribute because the assembly does not have a CLSCompliant attribute
+#pragma warning disable 3021
+}
+
+@lexer::namespace { Rellor.Core }
+@parser::namespace { Rellor.Core }
+
+WS	:	(' '|'\n'|'\r'|'\t')* {$channel=Hidden;}
+    ;
+
+DEC_INT
+    :	DEC_DIGIT+
+    ;
+
+HEX_INT
+    :	'$' HEX_DIGIT+
+    ;
+
+BIN_INT
+    :	'$$' BIN_DIGIT+
+    ;
+
+FLOAT
+    :	'$' ('+'|'-')
+        (DEC_DIGIT+ ('.' DEC_DIGIT*)? | '.' DEC_DIGIT+)
+        (('e' | 'E') ('+'|'-')? DEC_DIGIT+)?
+    ;
+
+HASHDOLLAR
+    :	'#' ('a'..'z') '$'
+    ;
+
+ICL_COMMENT
+	:	{allowIcl}? '!' '%' ~('\n'|'\r')* '\r'? '\n' { $channel = IclChannel; }
+	;
+
+COMMENT
+	:	'!' ~('\n'|'\r')* '\r'? '\n' { $channel = CommentChannel; }
+    ;
+
+SQ_STRING
+@init { int len = 0; }
+    :	'\'' (~('\'') { len++; })* '\''
+        { if (len == 1) $type = CHAR_LITERAL; }
+    ;
+
+DQ_STRING
+    :	'"' ~('"')* '"'
+    ;
+
+fragment
+DEC_DIGIT
+    :	('0'..'9')
+    ;
+
+fragment
+HEX_DIGIT
+    :	('0'..'9'|'a'..'f'|'A'..'F')
+    ;
+
+fragment
+BIN_DIGIT
+    :	('0'..'1')
+    ;
+
+fragment CHAR_LITERAL : ;	// suppress warning
+
+ID	:	('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
+        { keyword = LookupKeyword($text); }
+    ;
+
+/********************************** KEYWORDS **********************************/
+
+kBOX : {((RellorToken)input.LT(1)).Keyword == BOX}? ID -> BOX[$ID];
+kBREAK : {((RellorToken)input.LT(1)).Keyword == BREAK}? ID -> BREAK[$ID];
+kCONTINUE : {((RellorToken)input.LT(1)).Keyword == CONTINUE}? ID -> CONTINUE[$ID];
+kDEFAULTci : {((RellorToken)input.LT(1)).Keyword == DEFAULT}? ID -> DEFAULT[$ID];
+kDEFAULT : {((RellorToken)input.LT(1)).Keyword == DEFAULT}? ID -> DEFAULT[$ID];
+kDO : {((RellorToken)input.LT(1)).Keyword == DO}? ID -> DO[$ID];
+kELSE : {((RellorToken)input.LT(1)).Keyword == ELSE}? ID -> ELSE[$ID];
+kFONT : {((RellorToken)input.LT(1)).Keyword == FONT}? ID -> FONT[$ID];
+kFOR : {((RellorToken)input.LT(1)).Keyword == FOR}? ID -> FOR[$ID];
+kGIVE : {((RellorToken)input.LT(1)).Keyword == GIVE}? ID -> GIVE[$ID];
+kIF : {((RellorToken)input.LT(1)).Keyword == IF}? ID -> IF[$ID];
+kINVERSION : {((RellorToken)input.LT(1)).Keyword == INVERSION}? ID -> INVERSION[$ID];
+kJUMP : {((RellorToken)input.LT(1)).Keyword == JUMP}? ID -> JUMP[$ID];
+kMOVE : {((RellorToken)input.LT(1)).Keyword == MOVE}? ID -> MOVE[$ID];
+kNEW_LINE : {((RellorToken)input.LT(1)).Keyword == NEW_LINE}? ID -> NEW_LINE[$ID];
+kOBJECTLOOP : {((RellorToken)input.LT(1)).Keyword == OBJECTLOOP}? ID -> OBJECTLOOP[$ID];
+kPRINT : {((RellorToken)input.LT(1)).Keyword == PRINT}? ID -> PRINT[$ID];
+kPRINT_RET : {((RellorToken)input.LT(1)).Keyword == PRINT_RET}? ID -> PRINT_RET[$ID];
+kQUIT : {((RellorToken)input.LT(1)).Keyword == QUIT}? ID -> QUIT[$ID];
+kREAD : {((RellorToken)input.LT(1)).Keyword == READ}? ID -> READ[$ID];
+kREMOVE : {((RellorToken)input.LT(1)).Keyword == REMOVE}? ID -> REMOVE[$ID];
+kRESTORE : {((RellorToken)input.LT(1)).Keyword == RESTORE}? ID -> RESTORE[$ID];
+kRETURN : {((RellorToken)input.LT(1)).Keyword == RETURN}? ID -> RETURN[$ID];
+kRFALSE : {((RellorToken)input.LT(1)).Keyword == RFALSE}? ID -> RFALSE[$ID];
+kRTRUE : {((RellorToken)input.LT(1)).Keyword == RTRUE}? ID -> RTRUE[$ID];
+kSAVE : {((RellorToken)input.LT(1)).Keyword == SAVE}? ID -> SAVE[$ID];
+kSPACES : {((RellorToken)input.LT(1)).Keyword == SPACES}? ID -> SPACES[$ID];
+kSTRING : {((RellorToken)input.LT(1)).Keyword == STRING}? ID -> STRING[$ID];
+kSTYLE : {((RellorToken)input.LT(1)).Keyword == STYLE}? ID -> STYLE[$ID];
+kSWITCH : {((RellorToken)input.LT(1)).Keyword == SWITCH}? ID -> SWITCH[$ID];
+kUNTIL : {((RellorToken)input.LT(1)).Keyword == UNTIL}? ID -> UNTIL[$ID];
+kWHILE : {((RellorToken)input.LT(1)).Keyword == WHILE}? ID -> WHILE[$ID];
+kALIAS : {((RellorToken)input.LT(1)).Keyword == ALIAS}? ID -> ALIAS[$ID];
+kLONG : {((RellorToken)input.LT(1)).Keyword == LONG}? ID -> LONG[$ID];
+kADDITIVE : {((RellorToken)input.LT(1)).Keyword == ADDITIVE}? ID -> ADDITIVE[$ID];
+kSCORE : {((RellorToken)input.LT(1)).Keyword == SCORE}? ID -> SCORE[$ID];
+kTIME : {((RellorToken)input.LT(1)).Keyword == TIME}? ID -> TIME[$ID];
+kNOUN : {((RellorToken)input.LT(1)).Keyword == NOUN}? ID -> NOUN[$ID];
+kHELD : {((RellorToken)input.LT(1)).Keyword == HELD}? ID -> HELD[$ID];
+kMULTI : {((RellorToken)input.LT(1)).Keyword == MULTI}? ID -> MULTI[$ID];
+kMULTIHELD : {((RellorToken)input.LT(1)).Keyword == MULTIHELD}? ID -> MULTIHELD[$ID];
+kMULTIEXCEPT : {((RellorToken)input.LT(1)).Keyword == MULTIEXCEPT}? ID -> MULTIEXCEPT[$ID];
+kMULTIINSIDE : {((RellorToken)input.LT(1)).Keyword == MULTIINSIDE}? ID -> MULTIINSIDE[$ID];
+kCREATURE : {((RellorToken)input.LT(1)).Keyword == CREATURE}? ID -> CREATURE[$ID];
+kSPECIAL : {((RellorToken)input.LT(1)).Keyword == SPECIAL}? ID -> SPECIAL[$ID];
+kNUMBER : {((RellorToken)input.LT(1)).Keyword == NUMBER}? ID -> NUMBER[$ID];
+kSCOPE : {((RellorToken)input.LT(1)).Keyword == SCOPE}? ID -> SCOPE[$ID];
+kTOPIC : {((RellorToken)input.LT(1)).Keyword == TOPIC}? ID -> TOPIC[$ID];
+kREVERSE : {((RellorToken)input.LT(1)).Keyword == REVERSE}? ID -> REVERSE[$ID];
+kMETA : {((RellorToken)input.LT(1)).Keyword == META}? ID -> META[$ID];
+kONLY : {((RellorToken)input.LT(1)).Keyword == ONLY}? ID -> ONLY[$ID];
+kREPLACEci : {((RellorToken)input.LT(1)).Keyword == REPLACE}? ID -> REPLACE[$ID];
+kREPLACE : {((RellorToken)input.LT(1)).Keyword == REPLACE}? ID -> REPLACE[$ID];
+kFIRST : {((RellorToken)input.LT(1)).Keyword == FIRST}? ID -> FIRST[$ID];
+kLAST : {((RellorToken)input.LT(1)).Keyword == LAST}? ID -> LAST[$ID];
+kTABLE : {((RellorToken)input.LT(1)).Keyword == TABLE}? ID -> TABLE[$ID];
+kBUFFER : {((RellorToken)input.LT(1)).Keyword == BUFFER}? ID -> BUFFER[$ID];
+kDATA : {((RellorToken)input.LT(1)).Keyword == DATA}? ID -> DATA[$ID];
+kINITIAL : {((RellorToken)input.LT(1)).Keyword == INITIAL}? ID -> INITIAL[$ID];
+kINITSTR : {((RellorToken)input.LT(1)).Keyword == INITSTR}? ID -> INITSTR[$ID];
+kWITH : {((RellorToken)input.LT(1)).Keyword == WITH}? ID -> WITH[$ID];
+kPRIVATE : {((RellorToken)input.LT(1)).Keyword == PRIVATE}? ID -> PRIVATE[$ID];
+kHAS : {((RellorToken)input.LT(1)).Keyword == HAS}? ID -> HAS[$ID];
+kCLASSci : {((RellorToken)input.LT(1)).Keyword == CLASS}? ID -> CLASS[$ID];
+kCLASS : {((RellorToken)input.LT(1)).Keyword == CLASS}? ID -> CLASS[$ID];
+kERROR : {((RellorToken)input.LT(1)).Keyword == ERROR}? ID -> ERROR[$ID];
+kFATALERROR : {((RellorToken)input.LT(1)).Keyword == FATALERROR}? ID -> FATALERROR[$ID];
+kWARNING : {((RellorToken)input.LT(1)).Keyword == WARNING}? ID -> WARNING[$ID];
+kTERMINATING : {((RellorToken)input.LT(1)).Keyword == TERMINATING}? ID -> TERMINATING[$ID];
+kDICTIONARYci : {((RellorToken)input.LT(1)).Keyword == DICTIONARY}? ID -> DICTIONARY[$ID];
+kDICTIONARY : {((RellorToken)input.LT(1)).Keyword == DICTIONARY}? ID -> DICTIONARY[$ID];
+kSYMBOLS : {((RellorToken)input.LT(1)).Keyword == SYMBOLS}? ID -> SYMBOLS[$ID];
+kOBJECTS : {((RellorToken)input.LT(1)).Keyword == OBJECTS}? ID -> OBJECTS[$ID];
+kVERBS : {((RellorToken)input.LT(1)).Keyword == VERBS}? ID -> VERBS[$ID];
+kASSEMBLY : {((RellorToken)input.LT(1)).Keyword == ASSEMBLY}? ID -> ASSEMBLY[$ID];
+kEXPRESSIONS : {((RellorToken)input.LT(1)).Keyword == EXPRESSIONS}? ID -> EXPRESSIONS[$ID];
+kLINES : {((RellorToken)input.LT(1)).Keyword == LINES}? ID -> LINES[$ID];
+kTOKENS : {((RellorToken)input.LT(1)).Keyword == TOKENS}? ID -> TOKENS[$ID];
+kLINKER : {((RellorToken)input.LT(1)).Keyword == LINKER}? ID -> LINKER[$ID];
+kON : {((RellorToken)input.LT(1)).Keyword == ON}? ID -> ON[$ID];
+kOFF : {((RellorToken)input.LT(1)).Keyword == OFF}? ID -> OFF[$ID];
+kABBREVIATEci : {((RellorToken)input.LT(1)).Keyword == ABBREVIATE}? ID -> ABBREVIATE[$ID];
+kARRAYci : {((RellorToken)input.LT(1)).Keyword == ARRAY}? ID -> ARRAY[$ID];
+kATTRIBUTEci : {((RellorToken)input.LT(1)).Keyword == ATTRIBUTE}? ID -> ATTRIBUTE[$ID];
+kCONSTANTci : {((RellorToken)input.LT(1)).Keyword == CONSTANT}? ID -> CONSTANT[$ID];
+kENDci : {((RellorToken)input.LT(1)).Keyword == END}? ID -> END[$ID];
+kENDIFci : {((RellorToken)input.LT(1)).Keyword == ENDIF}? ID -> ENDIF[$ID];
+kEXTENDci : {((RellorToken)input.LT(1)).Keyword == EXTEND}? ID -> EXTEND[$ID];
+kFAKE_ACTIONci : {((RellorToken)input.LT(1)).Keyword == FAKE_ACTION}? ID -> FAKE_ACTION[$ID];
+kGLOBALci : {((RellorToken)input.LT(1)).Keyword == GLOBAL}? ID -> GLOBAL[$ID];
+kIFDEFci : {((RellorToken)input.LT(1)).Keyword == IFDEF}? ID -> IFDEF[$ID];
+kIFNDEFci : {((RellorToken)input.LT(1)).Keyword == IFNDEF}? ID -> IFNDEF[$ID];
+kIFNOTci : {((RellorToken)input.LT(1)).Keyword == IFNOT}? ID -> IFNOT[$ID];
+kIFV3ci : {((RellorToken)input.LT(1)).Keyword == IFV3}? ID -> IFV3[$ID];
+kIFV5ci : {((RellorToken)input.LT(1)).Keyword == IFV5}? ID -> IFV5[$ID];
+kIFTRUEci : {((RellorToken)input.LT(1)).Keyword == IFTRUE}? ID -> IFTRUE[$ID];
+kIFFALSEci : {((RellorToken)input.LT(1)).Keyword == IFFALSE}? ID -> IFFALSE[$ID];
+kIMPORTci : {((RellorToken)input.LT(1)).Keyword == IMPORT}? ID -> IMPORT[$ID];
+kINCLUDEci : {((RellorToken)input.LT(1)).Keyword == INCLUDE}? ID -> INCLUDE[$ID];
+kLINKci : {((RellorToken)input.LT(1)).Keyword == LINK}? ID -> LINK[$ID];
+kLOWSTRINGci : {((RellorToken)input.LT(1)).Keyword == LOWSTRING}? ID -> LOWSTRING[$ID];
+kMESSAGEci : {((RellorToken)input.LT(1)).Keyword == MESSAGE}? ID -> MESSAGE[$ID];
+kNEARBYci : {((RellorToken)input.LT(1)).Keyword == NEARBY}? ID -> NEARBY[$ID];
+kOBJECTci : {((RellorToken)input.LT(1)).Keyword == OBJECT}? ID -> OBJECT[$ID];
+kOBJECT : {((RellorToken)input.LT(1)).Keyword == OBJECT}? ID -> OBJECT[$ID];
+kPROPERTYci : {((RellorToken)input.LT(1)).Keyword == PROPERTY}? ID -> PROPERTY[$ID];
+kPROPERTY : {((RellorToken)input.LT(1)).Keyword == PROPERTY}? ID -> PROPERTY[$ID];
+kRELEASEci : {((RellorToken)input.LT(1)).Keyword == RELEASE}? ID -> RELEASE[$ID];
+kSERIALci : {((RellorToken)input.LT(1)).Keyword == SERIAL}? ID -> SERIAL[$ID];
+kSWITCHESci : {((RellorToken)input.LT(1)).Keyword == SWITCHES}? ID -> SWITCHES[$ID];
+kSTATUSLINEci : {((RellorToken)input.LT(1)).Keyword == STATUSLINE}? ID -> STATUSLINE[$ID];
+kSTUBci : {((RellorToken)input.LT(1)).Keyword == STUB}? ID -> STUB[$ID];
+kSYSTEM_FILEci : {((RellorToken)input.LT(1)).Keyword == SYSTEM_FILE}? ID -> SYSTEM_FILE[$ID];
+kTRACEci : {((RellorToken)input.LT(1)).Keyword == TRACE}? ID -> TRACE[$ID];
+kVERBci : {((RellorToken)input.LT(1)).Keyword == VERB}? ID -> VERB[$ID];
+kVERSIONci : {((RellorToken)input.LT(1)).Keyword == VERSION}? ID -> VERSION[$ID];
+kZCHARACTERci : {((RellorToken)input.LT(1)).Keyword == ZCHARACTER}? ID -> ZCHARACTER[$ID];
+kCHAR : {((RellorToken)input.LT(1)).Keyword == CHAR}? ID -> CHAR[$ID];
+kNAME : {((RellorToken)input.LT(1)).Keyword == NAME}? ID -> NAME[$ID];
+kTHE : {((RellorToken)input.LT(1)).Keyword == THE}? ID -> THE[$ID];
+kA : {((RellorToken)input.LT(1)).Keyword == A}? ID -> A[$ID];
+kAN : {((RellorToken)input.LT(1)).Keyword == AN}? ID -> AN[$ID];
+kROMAN : {((RellorToken)input.LT(1)).Keyword == ROMAN}? ID -> ROMAN[$ID];
+kBOLD : {((RellorToken)input.LT(1)).Keyword == BOLD}? ID -> BOLD[$ID];
+kUNDERLINE : {((RellorToken)input.LT(1)).Keyword == UNDERLINE}? ID -> UNDERLINE[$ID];
+kFIXED : {((RellorToken)input.LT(1)).Keyword == FIXED}? ID -> FIXED[$ID];
+kTO : {((RellorToken)input.LT(1)).Keyword == TO}? ID -> TO[$ID];
+kADDRESS : {((RellorToken)input.LT(1)).Keyword == ADDRESS}? ID -> ADDRESS[$ID];
+kNEAR : {((RellorToken)input.LT(1)).Keyword == NEAR}? ID -> NEAR[$ID];
+kFROM : {((RellorToken)input.LT(1)).Keyword == FROM}? ID -> FROM[$ID];
+kHASNT : {((RellorToken)input.LT(1)).Keyword == HASNT}? ID -> HASNT[$ID];
+kIN : {((RellorToken)input.LT(1)).Keyword == IN}? ID -> IN[$ID];
+kNOTIN : {((RellorToken)input.LT(1)).Keyword == NOTIN}? ID -> NOTIN[$ID];
+kOFCLASS : {((RellorToken)input.LT(1)).Keyword == OFCLASS}? ID -> OFCLASS[$ID];
+kOR : {((RellorToken)input.LT(1)).Keyword == OR}? ID -> OR[$ID];
+kPROVIDES : {((RellorToken)input.LT(1)).Keyword == PROVIDES}? ID -> PROVIDES[$ID];
+
+
+/**************************** TOP-LEVEL DIRECTIVES ****************************/
+
+public
+program
+scope { IScope globalScope; }
+scope Symbols, Quirks;
+@init { $program::globalScope = $Symbols::scope = new GlobalScope(); }
+    :	('#'!? directive[false] ';'!)*
+    ;
+
+directive[bool nested]
+options { k=1; }
+    :	include_directive
+    |	version_directive
+    |	release_directive
+    |	serial_directive
+    |	object_directive
+		{DefineSymbol($Symbols::scope, SymbolType.Object, $object_directive.name, $object_directive.tree);}
+    |	routine_directive
+		{DefineSymbol($Symbols::scope, SymbolType.Routine, $routine_directive.name, $routine_directive.tree);}
+    |	array_directive
+		{DefineSymbol($Symbols::scope, SymbolType.Array, $array_directive.name, $array_directive.tree);}
+    |	global_directive
+		{DefineSymbol($Symbols::scope, SymbolType.GlobalVar, $global_directive.name, $global_directive.tree);}
+    |	verb_directive
+    ;
+
+include_directive
+    :	kINCLUDEci fn=DQ_STRING
+    ;
+
+version_directive
+    :	kVERSIONci^ number
+    ;
+
+release_directive
+    :	kRELEASEci^ number
+    ;
+
+serial_directive
+    :	kSERIALci^ DQ_STRING
+    ;
+
+object_directive returns [ITree name]
+    :	kOBJECTci
+        ARROW*
+        n=id									// object identifier
+		{$name = $n.tree;}
+        sn=DQ_STRING?							// textual short name
+        p=id_not_seg?							// parent object
+        object_parts
+        -> ^(kOBJECTci $n ^(DEPTH ARROW*)? ^(SHORT_NAME $sn)? ^(PARENT $p)? object_parts)
+    |	kNEARBYci
+        n=id
+        sn=DQ_STRING?
+        p=id_not_seg?
+        object_parts
+        -> ^(OBJECT[$kNEARBYci.start] $n ^(DEPTH ARROW) ^(SHORT_NAME $sn)? ^(PARENT $p)? object_parts)
+    |	kCLASSci
+        n=id
+        object_parts
+        -> ^(kCLASSci $n object_parts)
+    ;
+
+object_parts
+    :	(	kHAS object_attr*
+        |	kCLASS cls+=id_not_seg+
+        |	kWITH wp+=object_property (options {k=2;} : (',' id_not_seg)=> ',' wp+=object_property)*
+        |	kPRIVATE pp+=object_property (options {k=2;} : (',' id_not_seg)=> ',' pp+=object_property)*
+        )?
+        (
+            ','?
+            (	kHAS object_attr*
+            |	kCLASS cls+=id_not_seg+
+            |	kWITH wp+=object_property (options {k=2;} : (',' id_not_seg)=> ',' wp+=object_property)*
+            |	kPRIVATE pp+=object_property (options {k=2;} : (',' id_not_seg)=> ',' pp+=object_property)*
+            )
+        )*
+        -> ^(kCLASS $cls+)? ^(kHAS object_attr*)? ^(kWITH $wp*)? ^(kPRIVATE $pp*)?
+    ;
+
+object_attr
+    :	NOT^ id_not_seg
+    |	id_not_seg
+    ;
+
+object_property
+scope Quirks;
+@init { $Quirks::no_func_calls = true; $Quirks::ambiguous_minus = true; }
+    :	id_not_seg^ property_value+
+    ;
+
+property_value
+    :	arg_expr
+    |	LSQUARE id* SEMI switch_body RSQUARE
+        -> ^(ROUTINE[$LSQUARE] OMITTED ^(LOCALS id*)? switch_body)
+    ;
+
+id_not_seg
+    :	{!IsKeyword((RellorToken)input.LT(1), CLASS, HAS, WITH, PRIVATE)}? id
+    ;
+    
+routine_directive returns [IScope routineScope, ITree name]
+scope Symbols;
+    :	LSQUARE n=id
+		{$routineScope = $Symbols::scope = new RoutineScope($Symbols[-1]::scope, $n.text);
+		 $name = $n.tree;}
+		STAR?
+		(l+=id {DefineSymbol($routineScope, SymbolType.LocalVar, l.Tree);})* SEMI
+		switch_body
+		RSQUARE
+		-> ^(ROUTINE[$LSQUARE] $n ^(FLAGS STAR?)? ^(LOCALS $l*)? switch_body)
+    ;
+
+array_directive returns [ITree name]
+    :	kARRAYci^ n=id array_initializer
+		{$name = $n.tree;}
+    ;
+
+array_initializer
+scope Quirks;
+@init { $Quirks::no_func_calls = true; $Quirks::ambiguous_minus = true; }
+    :	(	(	t=ARROW
+            |	t=DARROW
+            )
+            -> $t
+        |	(	k=kTABLE
+            |	k=kBUFFER
+            |	k=kSTRING
+            )
+            -> $k
+        )
+        (	(number ';')=> number
+            -> ^($array_initializer UNINITIALIZED<node=NumberTree>[$number.start, ((NumberTree)$number.tree).Number])
+        |	arg_expr+
+            -> ^($array_initializer arg_expr+)
+        )
+    ;
+
+global_directive returns [ITree name]
+    :	kGLOBALci n=id
+		{$name = $n.tree;}
+        (	/* nada */
+            -> ^(kGLOBALci $n)
+        |	EQ any_expr
+            -> ^(kGLOBALci $n any_expr)
+        |	array_initializer
+            -> ^(kGLOBALci $n ^(ARRAY array_initializer))
+        )
+    ;
+
+verb_directive
+@init { int verbs = 0; }
+    :	kVERBci kMETA? ((v+=DQ_STRING | v+=SQ_STRING) {verbs++;})+
+        (	EQ (vx=DQ_STRING|vx=SQ_STRING)
+        |	grammar_line+
+        )
+        -> ^(VERB ^(FLAGS kMETA?)? ^(SLASH $v+) ^(EQ $vx)? grammar_line*)
+    ;
+
+grammar_line
+    :	STAR grammar_token* ARROW id kREVERSE?
+        -> ^(id ^(FLAGS kREVERSE?)? grammar_token*)
+    ;
+
+grammar_token
+    :	id (EQ^ id)?
+    |	SQ_STRING (SLASH^ SQ_STRING)*
+    ;
+
+/**************************** STATEMENTS ****************************/
+
+statement
+    :	(print_stmt)=> print_stmt
+    |	new_line_stmt
+    |	if_stmt
+    |	while_stmt
+    |	do_stmt
+    |	for_stmt
+    |	objectloop_stmt
+    |	switch_stmt
+    |	continue_stmt
+    |	break_stmt
+    |	return_stmt
+    |	rfalse_stmt
+    |	rtrue_stmt
+    |	give_stmt
+    |	move_stmt
+    |	remove_stmt
+    |	box_stmt
+    |	font_stmt
+    |	style_stmt
+    |	quit_stmt
+    |	inversion_stmt
+    |	read_stmt
+    |	restore_stmt
+    |	save_stmt
+    |	spaces_stmt
+    |	string_stmt
+    |	jump_stmt
+    |	assembly_stmt
+    |	action_stmt	
+    |	expr_stmt
+    |	directive_stmt
+    |	label
+    |	block
+    |	null_stmt
+    ;
+    
+print_stmt
+    :	(pkw=kPRINT|pkw=kPRINT_RET) print_part (',' print_part)* ';'
+        -> ^($pkw print_part+)
+    |	DQ_STRING ';'
+        -> ^(PRINT_RET DQ_STRING)
+    ;
+
+print_part
+    :	('(' . ')')=> '(' id ')' arg_expr		-> ^(PRINT_AS id arg_expr)
+    |	arg_expr								-> arg_expr
+    ;
+    
+new_line_stmt
+    :	kNEW_LINE ';'!
+    ;
+
+if_stmt
+    :	kIF '(' any_expr ')' s1=statement ((kELSE)=> kELSE s2=statement)? -> ^(kIF any_expr $s1 $s2?)
+    ;
+
+while_stmt
+    :	kWHILE '(' any_expr ')' statement		-> ^(kWHILE any_expr statement)
+    ;
+
+do_stmt
+    :	kDO statement kUNTIL '(' any_expr ')' ';'	-> ^(kDO statement any_expr)
+    ;
+
+for_stmt
+	:	kFOR '(' for_exprs ')' statement
+		-> ^(kFOR for_exprs statement)
+	;
+
+for_exprs returns [bool used_semicolon]
+scope Quirks;
+	:	{$Quirks::no_superclass = true;}
+		(	init=any_expr
+			-> $init
+		|	/* nothing */
+			-> OMITTED
+		)
+		{$Quirks::no_superclass = false;}
+		(	('::' | (':' | ';' {$used_semicolon = true;}) (':' | ';' {$used_semicolon = true;}))
+			-> $for_exprs OMITTED
+		|	(':' | ';' {$used_semicolon = true;}) cond=any_expr (':' | ';' {$used_semicolon = true;})
+			-> $for_exprs $cond
+		)
+		(	step=any_expr
+			-> $for_exprs $step
+		|	/* nothing */
+			-> $for_exprs OMITTED
+		)
+	;
+
+objectloop_stmt
+    :	(i5_objectloop_stmt)=> i5_objectloop_stmt
+    |	kOBJECTLOOP '(' objectloop_expr ')' statement
+		-> ^(kOBJECTLOOP {$objectloop_expr.initialVariable} objectloop_expr statement)
+    ;
+
+i5_objectloop_stmt
+    :	kw=kOBJECTLOOP '(' id (t=kNEAR|t=kFROM|t=kIN) any_expr ')' statement
+        -> ^(OLD_OBJECTLOOP[$kw.start] id $t any_expr statement)
+    ;
+
+objectloop_expr returns [ITree initialVariable]
+scope { ITree objectLoopVar; }
+@init { IToken varToken = null; }
+	:	(	(id)=> {varToken = input.LT(1);} any_expr
+		|	any_expr
+		)
+		{$initialVariable = new CommonTree(varToken ?? new RellorToken(OMITTED));}
+		-> any_expr
+	;
+
+switch_stmt
+    :	kSWITCH^ '('! any_expr ')'! '{'! switch_body '}'!
+    ;
+
+switch_body
+    :	stmt_in_switch_body*
+		-> ^(BLOCK stmt_in_switch_body*)
+    ;
+
+stmt_in_switch_body
+	:	case_label ':' statement
+		-> {$case_label.is_default}?	^(DEFAULT[$case_label.start] statement)
+		->								^(CASE case_label statement)
+	|	statement
+	;
+
+case_label returns [bool is_default]
+    :	kDEFAULT {$is_default = true;}
+	|	case_ranges
+    ;
+
+case_ranges
+	:	case_range
+		(	(',' case_range)+
+			-> ^(OR case_range+)
+		|	/* no more */
+			-> case_range
+		)
+	;
+
+case_range
+	:	simple_constant
+		(	kTO simple_constant
+			-> ^(kTO simple_constant+)
+		|	/* no more */
+			-> simple_constant
+		)
+	;
+
+continue_stmt
+    :	kCONTINUE ';'!
+    ;
+
+break_stmt
+    :	kBREAK ';'!
+    ;
+
+return_stmt
+    :	kRETURN^ any_expr? ';'!
+    ;
+
+rfalse_stmt
+    :	kRFALSE ';'!
+    ;
+
+rtrue_stmt
+    :	kRTRUE ';'!
+    ;
+
+give_stmt
+    :	kGIVE^ arg_expr give_attribute+ ';'
+    ;
+
+give_attribute
+    :	('~')=> '~'^ arg_expr
+    |	arg_expr
+    ;
+
+move_stmt
+    :	kMOVE^ any_expr kTO! any_expr ';'!
+    ;
+
+remove_stmt
+    :	kREMOVE^ any_expr ';'!
+    ;
+
+box_stmt
+    :	kBOX^ DQ_STRING+ ';'!
+    ;
+
+font_stmt
+    :	kFONT^ (kON | kOFF) ';'!
+    ;
+
+style_stmt
+    :	kSTYLE^ (kROMAN|kREVERSE|kBOLD|kUNDERLINE|kFIXED) ';'!
+    ;
+
+quit_stmt
+    :	kQUIT^ ';'!
+    ;
+
+inversion_stmt
+    :	kINVERSION^ ';'!
+    ;
+
+read_stmt
+    :	kREAD^ any_expr any_expr id? ';'!
+    ;
+
+restore_stmt
+    :	kRESTORE^ id ';'!
+    ;
+
+save_stmt
+    :	kSAVE^ id ';'!
+    ;
+
+spaces_stmt
+    :	kSPACES^ any_expr ';'!
+    ;
+
+string_stmt
+    :	kSTRING^ any_expr atom_expr ';'!
+    ;
+
+block
+    :	ob='{' statement+ '}'
+		-> ^(BLOCK[$ob] statement+)
+    |	ob='{' '}' -> SEMI[$ob]
+    ;
+
+expr_stmt
+    :	any_expr ';'!
+    ;
+
+label
+    :	dot='.' id ';'
+        -> ^(LABEL[$dot] id)
+    ;
+
+jump_stmt
+    :	kJUMP^ id ';'!
+    ;
+
+directive_stmt
+    :	'#'^ directive[true] ';'!
+    ;
+
+null_stmt
+    :	';'!
+    ;
+
+assembly_stmt
+scope Quirks;
+@init { $Quirks::no_func_calls = true; $Quirks::ambiguous_minus = true; $Quirks::no_byte_deref = true; }
+    :	'@'
+        (opc1=id | opc2=DQ_STRING)
+        any_expr*
+        assembly_store_opt
+        assembly_branch_opt
+        ';'
+        -> ^('@' $opc1? $opc2? assembly_store_opt assembly_branch_opt any_expr*)
+    ;
+
+assembly_store_opt
+    :	'->' id		-> ^('->' id)
+    |	/* nada */	-> ^('->' OMITTED)
+    ;
+
+assembly_branch_opt
+    :	'?' assembly_branch_target	-> ^('?' assembly_branch_target)
+    |	/* nada */					-> ^('?' OMITTED)
+    ;
+
+assembly_branch_target
+    :	('~'^)? (kRTRUE | kRFALSE | id)
+    ;
+
+action_stmt
+    :	'<' action_body '>' ';' -> ^(INVOKE_ACTION action_body)
+    |	'<' '<' action_body '>' '>' ';' -> ^(INVOKE_ACTION_RET action_body)
+    ;
+
+action_body
+scope Quirks;
+@init { $Quirks::no_func_calls = true; }
+    :	(id | '(' any_expr ')')
+        /* XXX */
+    ;
+
+/**************************** IDENTIFIERS ****************************/
+
+id	:	ID
+        { if ($objectloop_expr.Count > 0 && $objectloop_expr::objectLoopVar == null)
+            $objectloop_expr::objectLoopVar = $tree; }
+    ;
+
+/* operator precedence:
+ * 0: ,
+ * 1: =
+ * 2: ~~ && ||
+ * 3: == ~= > >= < <= has hasnt in notin provides ofclass
+ * 4: or
+ * 5: + -
+ * 6: * / % & | ~
+ * 7: -> -->
+ * 8: unary-
+ * 9: ++ --
+ * 10: .& .# ..& ..#
+ * 11: function call
+ * 12: . ..
+ * 13: ::
+ */
+
+any_expr : comma_expr;
+arg_expr : assign_expr;
+
+simple_constant
+    :	number
+    |	id
+    |	HASHDOLLAR^ id
+    |	SQ_STRING^
+    |	DQ_STRING^
+    ;
+
+number
+    :	DEC_INT				-> INT<node=NumberTree>[$DEC_INT, ParseDecInt($DEC_INT.Text)]
+    |	HEX_INT				-> INT<node=NumberTree>[$HEX_INT, ParseHexInt($HEX_INT.Text)]
+    |	BIN_INT				-> INT<node=NumberTree>[$BIN_INT, ParseBinInt($BIN_INT.Text)]
+	|	FLOAT				-> INT<node=NumberTree>[$FLOAT, ParseFloat($FLOAT.Text)]
+    |	CHAR_LITERAL		-> INT<node=NumberTree>[$CHAR_LITERAL, ParseCharLiteral($CHAR_LITERAL.Text)]
+    ;
+
+atom_expr
+scope Quirks;
+    :	simple_constant
+    |	'('! comma_expr ')'!
+    ;
+
+comma_expr
+    :	assign_expr (','^ assign_expr)*
+    ;
+
+assign_expr
+    :	logical_expr ('='^ assign_expr)?
+    ;
+
+logical_expr
+    :	'~~'^ logical_expr
+    |   compare_expr
+        ( '&&'^ compare_expr
+        | '||'^ compare_expr)*
+    ;
+
+compare_expr
+    :	or_expr
+        ( '=='^ or_expr
+        | '~='^ or_expr
+        | '<'^ or_expr
+        | '<='^ or_expr
+        | '>'^ or_expr
+        | '>='^ or_expr
+        | kHAS^ or_expr
+        | kHASNT^ or_expr
+        | kIN^ or_expr
+        | kNOTIN^ or_expr
+        | kPROVIDES^ or_expr
+        | kOFCLASS^ or_expr)*
+    ;
+
+or_expr
+    :	(	a+=add_expr
+			-> $a+
+		)
+		(	(kOR a+=add_expr)+
+			-> ^(kOR $a+)
+		)?
+    ;
+
+add_expr
+    :	mul_expr
+        ( ('+')=> '+'^ mul_expr
+        | {$Quirks::ambiguous_minus == false}? ('-')=> '-'^ mul_expr)*
+    ;
+
+mul_expr
+    :	'~'^ mul_expr
+    |   array_expr
+        ( '*'^ array_expr
+        | '/'^ array_expr
+        | '%'^ array_expr
+        | '&'^ array_expr
+        | '|'^ array_expr)*
+    ;
+
+array_expr
+    :	uminus_expr
+        ( {$Quirks::no_byte_deref == false}? '->'^ uminus_expr
+        | '-->'^ uminus_expr)*
+    ;
+
+uminus_expr
+    :	{$Quirks::ambiguous_minus == false}? '-' uminus_expr -> ^(UMINUS uminus_expr)
+    |	preinc_expr
+    ;
+
+preinc_expr
+    :	'++'<PREINC>^ preinc_expr
+    |	'--'<PREDEC>^ preinc_expr
+    |	postinc_expr
+    ;
+
+postinc_expr
+    :	propaddr_expr (('++')=> '++'<POSTINC>^ | ('--')=> '--'<POSTDEC>^)?
+    ;
+
+propaddr_expr
+    :	func_expr
+        ( '.&'^ func_expr
+        | '.#'^ func_expr
+        | '..&'^ func_expr
+        | '..#'^ func_expr)*
+    ;
+
+func_expr
+    :	(e=prop_expr -> $e)
+        ({$Quirks::no_func_calls == false}?
+            ('(')=> p='(' (arg+=assign_expr (',' arg+=assign_expr)*)? ')'
+                -> ^(FUNCTION_CALL[$p] $func_expr $arg*)
+        )*
+    ;
+
+prop_expr
+    :	super_expr
+        ( '.'^ super_expr
+        | '..'^ super_expr)*
+    ;
+
+super_expr
+    :	atom_expr ({$Quirks::no_superclass == false}? '::'^ atom_expr)*
+    ;

File Rellor.Core/Inform6.g3.lexer.cs

+using System.Collections.Generic;
+using System.Diagnostics.Contracts;
+using Rellor.Core.Token;
+
+namespace Rellor.Core
+{
+    partial class Inform6Lexer
+    {
+        public const int CommentChannel = 2;
+        public const int IclChannel = 3;
+
+        private int keyword;
+        private bool allowIcl = true;
+
+        public override Antlr.Runtime.IToken Emit()
+        {
+            Contract.Ensures(Contract.Result<Antlr.Runtime.IToken>() is RellorToken);
+            Contract.Ensures(keyword == 0);
+
+            if (state.type != ICL_COMMENT && state.type != WS)
+                allowIcl = false;
+
+            RellorToken t = new RellorToken(input, state.type, state.channel, state.tokenStartCharIndex, CharIndex - 1)
+            {
+                Line = state.tokenStartLine,
+                Text = state.text,
+                CharPositionInLine = state.tokenStartCharPositionInLine,
+                Keyword = keyword,
+            };
+            Emit(t);
+
+            keyword = 0;
+            return t;
+        }
+
+        private static readonly Dictionary<string, int> caseSensitiveKeywords = new Dictionary<string, int>();
+        private static readonly Dictionary<string, int> caseInsensitiveKeywords = new Dictionary<string, int>();
+
+        static Inform6Lexer()
+        {
+            caseSensitiveKeywords.Add("box", BOX);
+            caseSensitiveKeywords.Add("break", BREAK);
+            caseSensitiveKeywords.Add("continue", CONTINUE);
+            caseInsensitiveKeywords.Add("default", DEFAULT);
+            caseSensitiveKeywords.Add("default", DEFAULT);
+            caseSensitiveKeywords.Add("do", DO);
+            caseSensitiveKeywords.Add("else", ELSE);
+            caseSensitiveKeywords.Add("font", FONT);
+            caseSensitiveKeywords.Add("for", FOR);
+            caseSensitiveKeywords.Add("give", GIVE);
+            caseSensitiveKeywords.Add("if", IF);
+            caseSensitiveKeywords.Add("inversion", INVERSION);
+            caseSensitiveKeywords.Add("jump", JUMP);
+            caseSensitiveKeywords.Add("move", MOVE);
+            caseSensitiveKeywords.Add("new_line", NEW_LINE);
+            caseSensitiveKeywords.Add("objectloop", OBJECTLOOP);
+            caseSensitiveKeywords.Add("print", PRINT);
+            caseSensitiveKeywords.Add("print_ret", PRINT_RET);
+            caseSensitiveKeywords.Add("quit", QUIT);
+            caseSensitiveKeywords.Add("read", READ);
+            caseSensitiveKeywords.Add("remove", REMOVE);
+            caseSensitiveKeywords.Add("restore", RESTORE);
+            caseSensitiveKeywords.Add("return", RETURN);
+            caseSensitiveKeywords.Add("rfalse", RFALSE);
+            caseSensitiveKeywords.Add("rtrue", RTRUE);
+            caseSensitiveKeywords.Add("save", SAVE);
+            caseSensitiveKeywords.Add("spaces", SPACES);
+            caseSensitiveKeywords.Add("string", STRING);
+            caseSensitiveKeywords.Add("style", STYLE);
+            caseSensitiveKeywords.Add("switch", SWITCH);
+            caseSensitiveKeywords.Add("until", UNTIL);
+            caseSensitiveKeywords.Add("while", WHILE);
+            caseSensitiveKeywords.Add("alias", ALIAS);
+            caseSensitiveKeywords.Add("long", LONG);
+            caseSensitiveKeywords.Add("additive", ADDITIVE);
+            caseSensitiveKeywords.Add("score", SCORE);
+            caseSensitiveKeywords.Add("time", TIME);
+            caseSensitiveKeywords.Add("noun", NOUN);
+            caseSensitiveKeywords.Add("held", HELD);
+            caseSensitiveKeywords.Add("multi", MULTI);
+            caseSensitiveKeywords.Add("multiheld", MULTIHELD);
+            caseSensitiveKeywords.Add("multiexcept", MULTIEXCEPT);
+            caseSensitiveKeywords.Add("multiinside", MULTIINSIDE);
+            caseSensitiveKeywords.Add("creature", CREATURE);
+            caseSensitiveKeywords.Add("special", SPECIAL);
+            caseSensitiveKeywords.Add("number", NUMBER);
+            caseSensitiveKeywords.Add("scope", SCOPE);
+            caseSensitiveKeywords.Add("topic", TOPIC);
+            caseSensitiveKeywords.Add("reverse", REVERSE);
+            caseSensitiveKeywords.Add("meta", META);
+            caseSensitiveKeywords.Add("only", ONLY);
+            caseInsensitiveKeywords.Add("replace", REPLACE);
+            caseSensitiveKeywords.Add("replace", REPLACE);
+            caseSensitiveKeywords.Add("first", FIRST);
+            caseSensitiveKeywords.Add("last", LAST);
+            caseSensitiveKeywords.Add("table", TABLE);
+            caseSensitiveKeywords.Add("buffer", BUFFER);
+            caseSensitiveKeywords.Add("data", DATA);
+            caseSensitiveKeywords.Add("initial", INITIAL);
+            caseSensitiveKeywords.Add("initstr", INITSTR);
+            caseSensitiveKeywords.Add("with", WITH);
+            caseSensitiveKeywords.Add("private", PRIVATE);
+            caseSensitiveKeywords.Add("has", HAS);
+            caseInsensitiveKeywords.Add("class", CLASS);
+            caseSensitiveKeywords.Add("class", CLASS);
+            caseSensitiveKeywords.Add("error", ERROR);
+            caseSensitiveKeywords.Add("fatalerror", FATALERROR);
+            caseSensitiveKeywords.Add("warning", WARNING);
+            caseSensitiveKeywords.Add("terminating", TERMINATING);
+            caseInsensitiveKeywords.Add("dictionary", DICTIONARY);
+            caseSensitiveKeywords.Add("dictionary", DICTIONARY);
+            caseSensitiveKeywords.Add("symbols", SYMBOLS);
+            caseSensitiveKeywords.Add("objects", OBJECTS);
+            caseSensitiveKeywords.Add("verbs", VERBS);
+            caseSensitiveKeywords.Add("assembly", ASSEMBLY);
+            caseSensitiveKeywords.Add("expressions", EXPRESSIONS);
+            caseSensitiveKeywords.Add("lines", LINES);
+            caseSensitiveKeywords.Add("tokens", TOKENS);
+            caseSensitiveKeywords.Add("linker", LINKER);
+            caseSensitiveKeywords.Add("on", ON);
+            caseSensitiveKeywords.Add("off", OFF);
+            caseInsensitiveKeywords.Add("abbreviate", ABBREVIATE);
+            caseInsensitiveKeywords.Add("array", ARRAY);
+            caseInsensitiveKeywords.Add("attribute", ATTRIBUTE);
+            caseInsensitiveKeywords.Add("constant", CONSTANT);
+            caseInsensitiveKeywords.Add("end", END);
+            caseInsensitiveKeywords.Add("endif", ENDIF);
+            caseInsensitiveKeywords.Add("extend", EXTEND);
+            caseInsensitiveKeywords.Add("fake_action", FAKE_ACTION);
+            caseInsensitiveKeywords.Add("global", GLOBAL);
+            caseInsensitiveKeywords.Add("ifdef", IFDEF);
+            caseInsensitiveKeywords.Add("ifndef", IFNDEF);
+            caseInsensitiveKeywords.Add("ifnot", IFNOT);
+            caseInsensitiveKeywords.Add("ifv3", IFV3);
+            caseInsensitiveKeywords.Add("ifv5", IFV5);
+            caseInsensitiveKeywords.Add("iftrue", IFTRUE);
+            caseInsensitiveKeywords.Add("iffalse", IFFALSE);
+            caseInsensitiveKeywords.Add("import", IMPORT);
+            caseInsensitiveKeywords.Add("include", INCLUDE);
+            caseInsensitiveKeywords.Add("link", LINK);
+            caseInsensitiveKeywords.Add("lowstring", LOWSTRING);
+            caseInsensitiveKeywords.Add("message", MESSAGE);
+            caseInsensitiveKeywords.Add("nearby", NEARBY);
+            caseInsensitiveKeywords.Add("object", OBJECT);
+            caseSensitiveKeywords.Add("object", OBJECT);
+            caseInsensitiveKeywords.Add("property", PROPERTY);
+            caseSensitiveKeywords.Add("property", PROPERTY);
+            caseInsensitiveKeywords.Add("release", RELEASE);
+            caseInsensitiveKeywords.Add("serial", SERIAL);
+            caseInsensitiveKeywords.Add("switches", SWITCHES);
+            caseInsensitiveKeywords.Add("statusline", STATUSLINE);
+            caseInsensitiveKeywords.Add("stub", STUB);
+            caseInsensitiveKeywords.Add("system_file", SYSTEM_FILE);
+            caseInsensitiveKeywords.Add("trace", TRACE);
+            caseInsensitiveKeywords.Add("verb", VERB);
+            caseInsensitiveKeywords.Add("version", VERSION);
+            caseInsensitiveKeywords.Add("zcharacter", ZCHARACTER);
+            caseSensitiveKeywords.Add("char", CHAR);
+            caseSensitiveKeywords.Add("name", NAME);
+            caseSensitiveKeywords.Add("the", THE);
+            caseSensitiveKeywords.Add("a", A);
+            caseSensitiveKeywords.Add("an", AN);
+            caseSensitiveKeywords.Add("roman", ROMAN);
+            caseSensitiveKeywords.Add("bold", BOLD);
+            caseSensitiveKeywords.Add("underline", UNDERLINE);
+            caseSensitiveKeywords.Add("fixed", FIXED);
+            caseSensitiveKeywords.Add("to", TO);
+            caseSensitiveKeywords.Add("address", ADDRESS);
+            caseSensitiveKeywords.Add("near", NEAR);
+            caseSensitiveKeywords.Add("from", FROM);
+            caseSensitiveKeywords.Add("hasnt", HASNT);
+            caseSensitiveKeywords.Add("in", IN);
+            caseSensitiveKeywords.Add("notin", NOTIN);
+            caseSensitiveKeywords.Add("ofclass", OFCLASS);
+            caseSensitiveKeywords.Add("or", OR);
+            caseSensitiveKeywords.Add("provides", PROVIDES);
+        }
+
+        private int LookupKeyword(string text)
+        {
+            Contract.Requires(text != null);
+            Contract.Ensures(Contract.Result<int>() >= 0);
+
+            int result;
+
+            if (caseSensitiveKeywords.TryGetValue(text, out result))
+                return result;
+
+            if (caseInsensitiveKeywords.TryGetValue(text.ToLowerInvariant(), out result))
+                return result;
+
+            return 0;
+        }
+    }
+}

File Rellor.Core/Inform6.g3.parser.cs

+using System;
+using System.Diagnostics.Contracts;
+using Antlr.Runtime;
+using Antlr.Runtime.Tree;
+using Rellor.Core.Token;
+using Rellor.Core.Tree;
+
+namespace Rellor.Core
+{
+    partial class Inform6Parser
+    {
+        /*public bool AllowExtensions { get; set; }
+        public bool BugCompatible { get; set; }*/
+
+        private static int ParseDecInt(string str)
+        {
+            Contract.Requires(str != null);
+
+            return int.Parse(str);
+        }
+
+        private static int ParseHexInt(string str)
+        {
+            Contract.Requires(str != null);
+
+            return Convert.ToInt32(str.Substring(1), 16);
+        }
+
+        private static int ParseBinInt(string str)
+        {
+            Contract.Requires(str != null);
+
+            return Convert.ToInt32(str.Substring(2), 2);
+        }
+
+        private static int ParseFloat(string str)
+        {
+            Contract.Requires(str != null);
+            
+            var value = float.Parse(str.Substring(1));
+            var bytes = BitConverter.GetBytes(value);
+
+            /*if (BitConverter.IsLittleEndian)
+            {
+                byte a = bytes[0], b = bytes[1], c = bytes[2], d = bytes[3];
+                bytes[0] = d;
+                bytes[1] = c;
+                bytes[2] = b;
+                bytes[3] = a;
+            }*/
+
+            return BitConverter.ToInt32(bytes, 0);
+        }
+
+        private static int ParseCharLiteral(string str)
+        {
+            Contract.Requires(str != null);
+            Contract.Requires(str.Length == 3);
+
+            return (int)str[1];
+        }
+
+        private static bool IsKeyword(RellorToken token, int kw1, int kw2 = -2, int kw3 = -2, int kw4 = -2)
+        {
+            Contract.Requires(token != null);
+
+            int tk = token.Keyword;
+            return tk == kw1 || tk == kw2 || tk == kw3 || tk == kw4;
+        }
+
+        private void DefineSymbol(IScope scope, SymbolType type, ITree identifier, ITree value = null)
+        {
+            Contract.Requires(scope != null);
+            Contract.Requires(identifier is CommonTree);
+
+            IToken token = ((CommonTree)identifier).Token;
+            Symbol symbol = new Symbol()
+            {
+                Name = token.Text,
+                Defined = true,
+                Declaration = identifier,
+                Type = type,
+                Value = value,
+            };
+            scope.Define(token.Text, symbol);
+        }
+
+        protected override object GetMissingSymbol(IIntStream input,
+                                       RecognitionException e,
+                                       int expectedTokenType,
+                                       BitSet follow)
+        {
+            Contract.Ensures(Contract.Result<object>() is RellorToken);
+
+            string tokenText = null;
+            if (expectedTokenType == TokenTypes.EndOfFile)
+                tokenText = "<missing EOF>";
+            else
+                tokenText = "<missing " + TokenNames[expectedTokenType] + ">";
+            RellorToken t = new RellorToken(expectedTokenType, tokenText);
+            IToken current = ((ITokenStream)input).LT(1);
+            if (current.Type == TokenTypes.EndOfFile)
+            {
+                current = ((ITokenStream)input).LT(-1);
+            }
+            t.Line = current.Line;
+            t.CharPositionInLine = current.CharPositionInLine;
+            t.Channel = DefaultTokenChannel;
+            t.InputStream = current.InputStream;
+            return t;
+        }
+
+        partial void CreateTreeAdaptor(ref ITreeAdaptor adaptor)
+        {
+            adaptor = new RellorTreeAdaptor();
+        }
+    }
+}

File Rellor.Core/Properties/AssemblyInfo.cs

+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Rellor")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Rellor")]
+[assembly: AssemblyCopyright("Copyright ©  2012")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("be172e11-e00b-4676-977d-f74ee9366b85")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]

File Rellor.Core/Rellor.Core.csproj

+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>8.0.30703</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{82B137B5-3F59-4CAD-B82D-C7DE1D2E8BC8}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>Rellor.Core</RootNamespace>
+    <AssemblyName>Rellor.Core</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <CodeContractsAssemblyMode>1</CodeContractsAssemblyMode>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeContractsEnableRuntimeChecking>True</CodeContractsEnableRuntimeChecking>
+    <CodeContractsRuntimeOnlyPublicSurface>False</CodeContractsRuntimeOnlyPublicSurface>
+    <CodeContractsRuntimeThrowOnFailure>True</CodeContractsRuntimeThrowOnFailure>
+    <CodeContractsRuntimeCallSiteRequires>False</CodeContractsRuntimeCallSiteRequires>
+    <CodeContractsRuntimeSkipQuantifiers>False</CodeContractsRuntimeSkipQuantifiers>
+    <CodeContractsRunCodeAnalysis>True</CodeContractsRunCodeAnalysis>
+    <CodeContractsNonNullObligations>False</CodeContractsNonNullObligations>
+    <CodeContractsBoundsObligations>False</CodeContractsBoundsObligations>
+    <CodeContractsArithmeticObligations>False</CodeContractsArithmeticObligations>
+    <CodeContractsEnumObligations>False</CodeContractsEnumObligations>
+    <CodeContractsRedundantAssumptions>False</CodeContractsRedundantAssumptions>
+    <CodeContractsInferRequires>False</CodeContractsInferRequires>
+    <CodeContractsInferEnsures>False</CodeContractsInferEnsures>
+    <CodeContractsInferObjectInvariants>False</CodeContractsInferObjectInvariants>
+    <CodeContractsSuggestAssumptions>True</CodeContractsSuggestAssumptions>
+    <CodeContractsSuggestRequires>True</CodeContractsSuggestRequires>
+    <CodeContractsSuggestEnsures>False</CodeContractsSuggestEnsures>
+    <CodeContractsSuggestObjectInvariants>False</CodeContractsSuggestObjectInvariants>
+    <CodeContractsDisjunctiveRequires>False</CodeContractsDisjunctiveRequires>
+    <CodeContractsRunInBackground>True</CodeContractsRunInBackground>
+    <CodeContractsShowSquigglies>True</CodeContractsShowSquigglies>
+    <CodeContractsUseBaseLine>False</CodeContractsUseBaseLine>
+    <CodeContractsEmitXMLDocs>False</CodeContractsEmitXMLDocs>
+    <CodeContractsCustomRewriterAssembly />
+    <CodeContractsCustomRewriterClass />
+    <CodeContractsLibPaths />
+    <CodeContractsExtraRewriteOptions />
+    <CodeContractsExtraAnalysisOptions />
+    <CodeContractsBaseLineFile />
+    <CodeContractsCacheAnalysisResults>False</CodeContractsCacheAnalysisResults>
+    <CodeContractsRuntimeCheckingLevel>Full</CodeContractsRuntimeCheckingLevel>
+    <CodeContractsReferenceAssembly>%28none%29</CodeContractsReferenceAssembly>
+    <CodeContractsAnalysisWarningLevel>0</CodeContractsAnalysisWarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="Antlr3.Runtime">
+      <HintPath>..\Reference\Antlr\Antlr3.Runtime.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Token\RellorToken.cs" />
+    <Compile Include="Token\RellorTokenStream.cs" />
+    <Compile Include="Tree\NumberTree.cs" />
+    <Compile Include="Tree\RellorTreeAdaptor.cs" />
+    <Compile Include="Scope.cs" />
+    <Compile Include="Symbol.cs" />
+    <Compile Include="Inform6.g3.lexer.cs">
+      <DependentUpon>Inform6.g3</DependentUpon>
+    </Compile>
+    <Compile Include="Inform6.g3.parser.cs">
+      <DependentUpon>Inform6.g3</DependentUpon>
+    </Compile>
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="SpecializeOperators.g3.cs">
+      <DependentUpon>SpecializeOperators.g3</DependentUpon>
+    </Compile>
+    <Compile Include="Tree\StringTree.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <Antlr3 Include="Inform6.g3">
+      <Generator>MSBuild:Compile</Generator>
+    </Antlr3>
+  </ItemGroup>
+  <ItemGroup>
+    <Antlr3 Include="SpecializeOperators.g3">
+      <Generator>MSBuild:Compile</Generator>
+    </Antlr3>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+  <PropertyGroup>
+    <!-- Folder containing AntlrBuildTask.dll -->
+    <AntlrBuildTaskPath>$(ProjectDir)..\Reference\Antlr</AntlrBuildTaskPath>
+    <!-- Path to the ANTLR Tool itself. -->
+    <AntlrToolPath>$(ProjectDir)..\Reference\Antlr\Antlr3.exe</AntlrToolPath>
+  </PropertyGroup>
+  <Import Project="$(ProjectDir)..\Reference\Antlr\Antlr3.targets" />
+</Project>

File Rellor.Core/Scope.cs

+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Diagnostics.Contracts;
+
+namespace Rellor.Core
+{
+    [ContractClass(typeof(IScopeContract))]
+    public interface IScope
+    {
+        string Name { get; }
+        Symbol Resolve(string name);
+        void Define(string name, Symbol symbol);
+    }
+
+    [ContractClassFor(typeof(IScope))]
+    internal abstract class IScopeContract : IScope
+    {
+        string IScope.Name
+        {
+            get
+            {
+                Contract.Ensures(Contract.Result<string>() != null);
+                return default(string);
+            }
+        }
+
+        [Pure]
+        Symbol IScope.Resolve(string name)
+        {
+            Contract.Requires(name != null);
+            return default(Symbol);
+        }
+
+        void IScope.Define(string name, Symbol symbol)
+        {
+            Contract.Requires(name != null);
+            Contract.Requires(symbol != null);
+        }
+    }
+
+    abstract class ScopeBase : IScope
+    {
+        protected readonly IScope enclosingScope;
+
+        protected readonly Dictionary<string, Symbol> dict = new Dictionary<string, Symbol>();
+
+        protected ScopeBase(IScope enclosingScope)
+        {
+            Contract.Ensures(dict.Count == 0);
+            Contract.Ensures(this.enclosingScope == enclosingScope);
+
+            this.enclosingScope = enclosingScope;
+        }
+
+        [ContractInvariantMethod]
+        private void ObjectInvariant()
+        {
+            Contract.Invariant(Name != null);
+            Contract.Invariant(dict != null);
+        }
+
+        public abstract string Name { get; }
+
+        public virtual Symbol Resolve(string name)
+        {
+            Symbol result;
+            if (dict.TryGetValue(name, out result))
+                return result;
+
+            if (enclosingScope != null)
+                return enclosingScope.Resolve(name);
+
+            return null;
+        }
+
+        public virtual void Define(string name, Symbol symbol)
+        {
+            Contract.Ensures(dict.ContainsKey(name));
+
+            dict.Add(name, symbol);
+        }
+    }
+
+    class GlobalScope : ScopeBase
+    {
+        public GlobalScope()
+            : base(null)
+        {
+        }
+
+        public override string Name
+        {
+            get { return "<global>"; }
+        }
+    }
+
+    class RoutineScope : ScopeBase
+    {
+        public RoutineScope(IScope enclosingScope, string routineName)
+            : base(enclosingScope)
+        {
+            Contract.Requires(routineName != null);
+
+            this.RoutineName = routineName;
+        }
+
+        [ContractInvariantMethod]
+        private void ObjectInvariant()
+        {
+            Contract.Invariant(RoutineName != null);
+        }
+
+        public string RoutineName { get; set; }
+
+        public override string Name
+        {
+            get
+            {
+                Contract.Ensures(Contract.Result<string>() == RoutineName);
+
+                return RoutineName;
+            }
+        }
+    }
+}

File Rellor.Core/SpecializeOperators.g3

+tree grammar SpecializeOperators;
+
+options {
+    language = CSharp3;
+    ASTLabelType = CommonTree;
+    output = AST;
+    tokenVocab = Inform6;
+    filter = true;
+}
+
+@namespace{Rellor.Core}
+
+@header {
+// 'class' does not need a CLSCompliant attribute because the assembly does not have a CLSCompliant attribute
+#pragma warning disable 3021
+
+using System;
+}
+
+public
+topdown
+    :	common_to_indiv_prop
+    ;
+
+common_to_indiv_prop
+    :	^(op=DOT x=. y=ID) {IsIndivProp($y)}?
+        -> ^(DOTDOT[$op.Token] $x $y)
+    ;
+
+public
+bottomup
+    :	synth_method
+	|	synth_assign
+	|	synth_preinc
+    |	synth_postinc
+    |	synth_predec
+    |	synth_postdec
+    ;
+
+synth_method
+    :	^(op=FUNCTION_CALL lhs=synth_inner rhs=.)
+		{$lhs.methodCall != 0}?
+        -> ^({SynthesizeOp($lhs.methodCall, $lhs.optext + "()", $op)} {$lhs.inner_lhs} {$lhs.inner_rhs} $rhs)
+	;
+
+synth_assign
+    :	^(op='=' lhs=synth_inner rhs=.)
+        -> ^({SynthesizeOp($lhs.assign, $lhs.optext + "=", $op)} {$lhs.inner_lhs} {$lhs.inner_rhs} $rhs)
+    ;
+
+synth_preinc
+    :	^(op=PREINC lhs=synth_inner)
+        -> ^({SynthesizeOp($lhs.preinc, "inc" + $lhs.optext, $op)} {$lhs.inner_lhs} {$lhs.inner_rhs})
+    ;
+
+synth_postinc
+    :	^(op=POSTINC lhs=synth_inner)
+        -> ^({SynthesizeOp($lhs.postinc, $lhs.optext + "inc", $op)} {$lhs.inner_lhs} {$lhs.inner_rhs})
+    ;
+
+synth_predec
+    :	^(op=PREDEC lhs=synth_inner)
+        -> ^({SynthesizeOp($lhs.predec, "dec" + $lhs.optext, $op)} {$lhs.inner_lhs} {$lhs.inner_rhs})
+    ;
+
+synth_postdec
+    :	^(op=POSTDEC lhs=synth_inner)
+        -> ^({SynthesizeOp($lhs.postdec, $lhs.optext + "dec", $op)} {$lhs.inner_lhs} {$lhs.inner_rhs})
+    ;
+
+synth_inner returns [int methodCall, int assign, int preinc, int postinc, int predec, int postdec,
+						ITree inner_lhs, ITree inner_rhs, string optext]
+    :	^(op=synth_inner_op l=. r=.)
+		{ $methodCall = $op.methodCall; $assign = $op.assign; $preinc = $op.preinc;
+		  $postinc = $op.postinc; $predec = $op.predec; $postdec = $op.postdec;
+		  $inner_lhs = $l; $inner_rhs = $r; $optext = ($op.tree).Token.Text; }
+    ;
+
+synth_inner_op returns [int methodCall, int assign, int preinc, int postinc, int predec, int postdec]
+	:	DOT
+        { $methodCall = COMMON_METHOD_CALL; $assign = COMMON_PROP_ASSIGN;
+          $preinc = COMMON_PROP_PREINC; $predec = COMMON_PROP_PREDEC;
+          $postinc = COMMON_PROP_POSTINC; $postdec = COMMON_PROP_POSTDEC; }
+    |	DOTDOT 
+        { $methodCall = INDIV_METHOD_CALL; $assign = INDIV_PROP_ASSIGN;
+          $preinc = INDIV_PROP_PREINC; $predec = INDIV_PROP_PREDEC;
+          $postinc = INDIV_PROP_POSTINC; $postdec = INDIV_PROP_POSTDEC; }
+    |	ARROW
+        { $methodCall = 0; $assign = BYTE_ARRAY_ASSIGN;
+          $preinc = BYTE_ARRAY_PREINC; $predec = BYTE_ARRAY_PREDEC;
+          $postinc = BYTE_ARRAY_POSTINC; $postdec = BYTE_ARRAY_POSTDEC; }
+    |	DARROW
+        { $methodCall = 0; $assign = WORD_ARRAY_ASSIGN;
+          $preinc = WORD_ARRAY_PREINC; $predec = WORD_ARRAY_PREDEC;
+          $postinc = WORD_ARRAY_POSTINC; $postdec = WORD_ARRAY_POSTDEC; }
+	;

File Rellor.Core/SpecializeOperators.g3.cs

+using System;
+using System.Diagnostics.Contracts;
+using Antlr.Runtime.Tree;
+using Rellor.Core.Token;
+
+namespace Rellor.Core
+{
+    partial class SpecializeOperators
+    {
+        private ITree SynthesizeOp(int type, string text, ITree oldOp)
+        {
+            Contract.Requires(text != null);
+            Contract.Requires(oldOp != null);
+            Contract.Ensures(Contract.Result<ITree>() is CommonTree);
+
+            var oldToken = ((CommonTree)oldOp).Token;
+            var newToken = new RellorToken(oldToken);
+            newToken.Type = type;
+            newToken.Text = text;
+            return new CommonTree(newToken);
+        }
+
+        private bool IsIndivProp(object wuteva)
+        {
+            Contract.Requires(wuteva != null);
+
+            //XXX
+            return false;
+        }
+    }
+}

File Rellor.Core/Symbol.cs

+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Antlr.Runtime.Tree;
+using System.ComponentModel;
+
+namespace Rellor.Core
+{
+    public enum SymbolType
+    {
+        Constant,
+        Object,
+        Class,
+        Routine,
+        Property,
+        Attribute,
+        [Description("global variable")]
+        GlobalVar,
+        [Description("local variable")]
+        LocalVar,
+        Array,
+        Label,
+    }
+
+    public class Symbol
+    {
+        public Symbol()
+        {
+        }
+
+        public string Name { get; set; }
+        public SymbolType Type { get; set; }
+        public ITree Declaration { get; set; }
+        public bool Defined { get; set; }
+        public bool Referenced { get; set; }
+        public object Value { get; set; }
+    }
+}

File Rellor.Core/Token/RellorToken.cs

+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Antlr.Runtime;
+using System.Diagnostics.Contracts;
+
+namespace Rellor.Core.Token
+{
+    public class RellorToken : CommonToken
+    {
+        public RellorToken()
+            : base()
+        {
+            Contract.Ensures(Keyword == 0);
+        }
+
+        public RellorToken(int type)
+            : base(type)
+        {
+            Contract.Ensures(Keyword == 0);
+        }
+
+
+        public RellorToken(IToken oldToken)
+            : base(oldToken)
+        {
+            Contract.Ensures(Keyword == 0);
+        }
+
+
+        public RellorToken(int type, string text)
+            : base(type, text)
+        {
+            Contract.Ensures(Keyword == 0);
+        }
+
+
+        public RellorToken(ICharStream input, int type, int channel, int start, int stop)
+            : base(input, type, channel, start, stop)
+        {
+            Contract.Ensures(Keyword == 0);
+        }
+
+        public int Keyword { get; set; }
+
+        [ContractInvariantMethod]
+        private void ObjectInvariant()
+        {
+            Contract.Invariant(Keyword >= 0);
+        }
+    }
+}

File Rellor.Core/Token/RellorTokenStream.cs

+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Antlr.Runtime;
+
+namespace Rellor.Core.Token
+{
+    public class RellorTokenStream : CommonTokenStream
+    {
+        protected static RellorToken RellorEofToken = new RellorToken(TokenTypes.EndOfFile);
+
+        public RellorTokenStream()
+            : base() { }
+
+        public RellorTokenStream(ITokenSource source)
+            : base(source) { }
+
+        public RellorTokenStream(ITokenSource source, int channel)
+            : base(source, channel) { }
+
+        public override IToken LT(int k)
+        {
+            IToken token = base.LT(k);
+            return token.Type == TokenTypes.EndOfFile ? RellorEofToken : token;
+        }
+    }
+}

File Rellor.Core/Tree/NumberTree.cs

+using System.Diagnostics.Contracts;
+using Antlr.Runtime;
+using Antlr.Runtime.Tree;
+using Rellor.Core.Token;
+
+namespace Rellor.Core.Tree
+{
+    public class NumberTree : CommonTree
+    {
+        public int Number { get; private set; }
+
+        public NumberTree(int ttype, int number)
+            : this(ttype, new RellorToken(ttype), number) { }
+
+        public NumberTree(int ttype, IToken token, int number)
+            : base(token.Type == ttype ? token : new RellorToken(token) { Type = ttype })
+        {
+            Contract.Requires(token != null);
+
+            this.Number = number;
+        }
+    }
+}

File Rellor.Core/Tree/RellorTreeAdaptor.cs

+using System.Diagnostics.Contracts;
+using Antlr.Runtime.Tree;
+using Rellor.Core.Token;
+
+namespace Rellor.Core.Tree
+{
+    public class RellorTreeAdaptor : CommonTreeAdaptor
+    {
+        public override Antlr.Runtime.IToken CreateToken(int tokenType, string text)
+        {
+            Contract.Ensures(Contract.Result<Antlr.Runtime.IToken>() is RellorToken);
+
+            return new RellorToken(tokenType, text);
+        }
+
+        public override Antlr.Runtime.IToken CreateToken(Antlr.Runtime.IToken fromToken)
+        {
+            Contract.Ensures(Contract.Result<Antlr.Runtime.IToken>() is RellorToken);
+
+            return new RellorToken(fromToken);
+        }
+    }
+}

File Rellor.Core/Tree/StringTree.cs

+using System.Diagnostics.Contracts;
+using Antlr.Runtime;
+using Antlr.Runtime.Tree;
+using Rellor.Core.Token;
+
+namespace Rellor.Core.Tree
+{
+    public class StringTree : CommonTree
+    {
+        public string String { get; private set; }
+
+        public StringTree(int ttype, string str)
+            : this(ttype, new RellorToken(ttype), str) { }
+
+        public StringTree(int ttype, IToken token, string str)
+            : base(token.Type == ttype ? token : new RellorToken(token) { Type = ttype })
+        {
+            Contract.Requires(token != null);
+            Contract.Requires(str != null);
+
+            this.String = str;
+        }
+    }
+}

File Rellor.Interpreter/Rellor.Interpreter.csproj

     <Compile Include="Properties\AssemblyInfo.cs" />
   </ItemGroup>
   <ItemGroup>
-    <ProjectReference Include="..\Rellor\Rellor.Core.csproj">
+    <ProjectReference Include="..\Rellor.Core\Rellor.Core.csproj">
       <Project>{82B137B5-3F59-4CAD-B82D-C7DE1D2E8BC8}</Project>
       <Name>Rellor.Core</Name>
     </ProjectReference>
 
 Microsoft Visual Studio Solution File, Format Version 11.00
 # Visual Studio 2010
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Rellor.Core", "Rellor\Rellor.Core.csproj", "{82B137B5-3F59-4CAD-B82D-C7DE1D2E8BC8}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Rellor.Core", "Rellor.Core\Rellor.Core.csproj", "{82B137B5-3F59-4CAD-B82D-C7DE1D2E8BC8}"
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RellorC", "RellorC\RellorC.csproj", "{5F5BD423-7740-40DD-9519-35F87DC0E2D7}"
 EndProject