📄 tinybasic.g
字号:
integerArrayVariable : integerVariable ;stringArrayVariable : stringVariable ;floatArrayVariable : floatVariable ; arrayVariable : integerArrayVariable | stringArrayVariable | floatArrayVariable ; graphicsOutput : "brush"^ integerExpression | "circle"^ LPAREN! integerExpression COMMA integerExpression RPAREN! COMMA integerExpression ( COMMA integerExpression )? | "clear"^ ("metafileon" | "metafileoff" )? | "ellipse"^ LPAREN! integerExpression COMMA integerExpression RPAREN! MINUS LPAREN! integerExpression COMMA integerExpression RPAREN! ( COMMA integerExpression )? | "font"^ integerExpression ( COMMA integerExpression ( COMMA integerExpression )? )? | "loc"^ integerStore COMMA integerStore | "pen"^ integerExpression COMMA integerExpression COMMA integerExpression | "picture"^ stringExpression COMMA LPAREN! integerExpression COMMA integerExpression RPAREN! ( COMMA integerExpression )? | "polyline"^ integerArrayVariable LPAREN COMMA RPAREN ( COMMA integerExpression )? | "rectangle"^ LPAREN! integerExpression COMMA integerExpression RPAREN! MINUS LPAREN! integerExpression COMMA integerExpression RPAREN! ( COMMA integerExpression )? | "screen"^ ( "normal" | "condensed" | "display" | "zoom" | "unzoom" | "close_basic" ) ; line_stuff // ambiguity forced left factoring : "line" ( "input" (chanNumber)? stringStore | "enter" combinationAddress (prompt)? stringStore ("until" integerExpression)? | (LPAREN! integerExpression COMMA integerExpression RPAREN!)? MINUS LPAREN! integerExpression COMMA integerExpression RPAREN! ( COMMA integerExpression )? ) ;eventSingleStatements : "cause" ("error")? integerExpression | "cause" "event" integerExpression | ("disable" | "enable") ("srq"|"timer"|"gpib") ("discard")? | ("disable" | "enable") "event" integerExpression ("discard")? | "error" ( "abort" integerExpression | "retry" | "continue" | "stop" ) | "on" ( "event" integerExpression | "srq" | "timer" | "gpib" ) "call" subName ;eventCompoundStatements : w:"when"^ "error" ( "call"^ subName (LPAREN! argList RPAREN!)? eol! {#w.setType(WHEN_ERROR_CALL);} | "in"! eol! {#w.setType(WHEN_ERROR_IN);} (singleStatement)+ "use"^ eol! (singleStatement)+ ("end"! "when"! | "endwhen"!) eol ) ;subName : IDENT ;expression : numericExpression | stringExpression ;argList : arg ( COMMA! arg )* {#argList = #(#[ARGLIST,"ARGLIST"], argList);} ; arg : //(variable LPAREN COMMA)=> //variable LPAREN COMMA {dimCount=2;} ( COMMA {dimCount++;} )* RPAREN (argArray)=>argArray //| (variable LPAREN RPAREN)=> //variable LPAREN RPAREN | expression ;argArray : (variable LPAREN COMMA)=> v23:variable LPAREN! COMMA! ( COMMA! { #v23.setType(ARRAY3D); } | { #v23.setType(ARRAY2D); } ) RPAREN! | //(variable LPAREN RPAREN)=> v1:variable LPAREN RPAREN { #v1.setType(ARRAY1D); } ; // assignment expression (level 13)assignmentExpression : stringStore EQ^ stringExpression | integerStore EQ^ integerExpression | floatStore EQ^ numericExpression ;stringStore : (stringVariable LPAREN)=> {theContext.isArrayVariable(LT(1).getText())}? stringVariable lp:LPAREN^ {#lp.setType(INDEX_OP);} indices RPAREN | (stringVariable LBRACK)=> stringVariable lb:LBRACK^ {#lb.setType(SUBSTRING_OP);} integerExpression COLON! integerExpression RBRACK! | stringVariable ; integerStore : ( integerVariable LPAREN )=> {theContext.isArrayVariable(LT(1).getText())}? integerVariable lp:LPAREN^ {#lp.setType(INDEX_OP);} indices RPAREN! | integerVariable ; floatStore : ( floatVariable LPAREN )=> {theContext.isArrayVariable(LT(1).getText())}? floatVariable lp:LPAREN^ {#lp.setType(INDEX_OP);} indices RPAREN! | floatVariable ; numericStore : integerStore | floatStore ;stringVariable : STR_VAR ; integerVariable : INT_VAR ; floatVariable : ( FLT_VAR | IDENT ) ;// boolean relational expressions (level 5)relationalExpression : relationalXORExpression ;relationalXORExpression : relationalORExpression ( "xor"^ relationalORExpression )* ;relationalORExpression : relationalANDExpression ( "or"^ relationalANDExpression )* ;relationalANDExpression : relationalNOTExpression ( "and"^ relationalNOTExpression )* ;relationalNOTExpression : ("not"^)? primaryRelationalExpression ;primaryRelationalExpression : (numericExpression)=> numericExpression ( LT^ | GT^ | LE^ | GE^ | e1:EQ^ {#e1.setType( EQ_COMP );} | NE_COMP^ ) numericExpression | stringExpression ( LT^ | GT^ | LE^ | GE^ | e2:EQ^ {#e2.setType( EQ_COMP );} | NE_COMP^ ) stringExpression | LPAREN! relationalExpression RPAREN! ; numericValuedFunctionExpression : "abs"^ LPAREN! numericExpression RPAREN! | "acos"^ LPAREN! numericExpression RPAREN! | "asc"^ LPAREN! stringExpression RPAREN! | "atn"^ LPAREN! numericExpression RPAREN! | "cos"^ LPAREN! numericExpression RPAREN! | "dround"^ LPAREN! numericExpression COMMA! integerExpression RPAREN! | "errl"^ | "errn"^ | "exp"^ LPAREN! numericExpression RPAREN! | "fract"^ LPAREN! numericExpression RPAREN! | "get_event"^ LPAREN! numericExpression RPAREN! | "in"^ LPAREN! numericExpression RPAREN! | "instr"^ LPAREN! stringExpression COMMA! stringExpression RPAREN! | "int"^ LPAREN! numericExpression RPAREN! | "ival"^ LPAREN! stringExpression RPAREN! | "len"^ LPAREN! stringExpression RPAREN! | "lgt"^ LPAREN! numericExpression RPAREN! | "log"^ LPAREN! numericExpression RPAREN! | "max"^ LPAREN! (numericExpression)+ RPAREN! | "min"^ LPAREN! (numericExpression)+ RPAREN! | "peek"^ LPAREN! numericExpression COMMA! integerExpression RPAREN! | "pi"^ | "rnd"^ | "sgn"^ LPAREN! numericExpression RPAREN! | "signed"^ LPAREN! integerExpression RPAREN! | "sin"^ LPAREN! numericExpression RPAREN! | "sqr"^ LPAREN! numericExpression RPAREN! | "tan"^ LPAREN! numericExpression RPAREN! | "time"^ | "ubound"^ LPAREN! stringExpression COMMA! integerExpression RPAREN! | "val"^ LPAREN! stringExpression RPAREN! // BIT Functions | "andb"^ LPAREN! integerExpression COMMA! integerExpression RPAREN! | "orb"^ LPAREN! integerExpression COMMA! integerExpression RPAREN! | "notb"^ LPAREN! integerExpression RPAREN! | "shiftb"^ LPAREN! integerExpression COMMA! integerExpression RPAREN! | "xorb"^ LPAREN! integerExpression COMMA! integerExpression RPAREN! ;integerExpression : numericExpression ;stringValuedFunctionExpression : "chr$"^ LPAREN! integerExpression RPAREN! | "date$"^ | "dround$"^ LPAREN! numericExpression COMMA! integerExpression RPAREN! | "errl$"^ | "errn$"^ LPAREN! integerExpression RPAREN! | "inchr$"^ | "ival$"^ LPAREN! integerExpression COMMA! integerExpression RPAREN! | "lwc$"^ LPAREN! stringExpression RPAREN! | "rpt$"^ LPAREN! stringExpression COMMA! integerExpression RPAREN! | "time$"^ | "upc$"^ LPAREN! stringExpression RPAREN! | "val$"^ LPAREN! numericExpression RPAREN! ;//numericExpression// : numericAdditiveExpression// ;// binary addition/subtraction (level 3)numericExpression : numericMultiplicativeExpression ( options {
warnWhenFollowAmbig = false;
} : (PLUS^ | MINUS^) numericMultiplicativeExpression )* ;// multiplication/division/modulo (level 2) numericMultiplicativeExpression : numericExponentialExpression ((STAR^ | "div"^ | "mod"^ | SLASH^ ) numericExponentialExpression)* ;numericExponentialExpression : numericUnaryExpression ( EXPO^ numericUnaryExpression)* ;numericUnaryExpression: ( p:PLUS^ {#p.setType(UNARY_PLUS);} | m:MINUS^ {#m.setType(UNARY_PLUS);} )? numericPrimaryExpression ;numericPrimaryExpression : floatNumber | numericStore | //(FLT_FN|INT_FN)=> ( FLT_FN^ {#FLT_FN.setType(FLT_FN_EXECUTE);} | INT_FN^ {#INT_FN.setType(INT_FN_EXECUTE);} ) ( (LPAREN)=> LPAREN argList RPAREN | ) | numericValuedFunctionExpression | e:LPAREN! numericExpression RPAREN! ;floatNumber : integerNumber | FLT_CONST ;stringExpression : stringConcatanateExpression ;// binary addition/subtraction (level 3)stringConcatanateExpression : stringPrimaryExpression ( AMPERSAND^ stringConcatanateExpression)? ;stringPrimaryExpression : stringStore | stringConstant | STR_FN^ ((LPAREN)=>LPAREN! argList RPAREN!)? {#STR_FN.setType(STR_FN_EXECUTE);} | stringValuedFunctionExpression ;indices : numericExpression (COMMA! indices)? ;stringConstant : STR_CONST ;integerNumber : INT_CONST | BINARY_INTEGER | OCTAL_INTEGER | HEXADECIMAL_INTEGER ;newVariable returns [int t] { t=0;} : INT_VAR { t=INT_VAR; } | STR_VAR { t=STR_VAR; } | FLT_VAR { t=FLT_VAR; } | IDENT { t=FLT_VAR; } ; variable : numericStore | stringStore ; eol! : ( options {
warnWhenFollowAmbig = false;
} : EOL! )+ ;//----------------------------------------------------------------------------//----------------------------------------------------------------------------// The TinyBasic scanner//----------------------------------------------------------------------------//----------------------------------------------------------------------------class TinyBasicLexer extends Lexer;options { importVocab=TinyBasic; // call the vocabulary "TinyBasic" testLiterals=true; // automatically test for literals k=6; // four characters of lookahead caseSensitive=false; caseSensitiveLiterals = false;}// OPERATORSAMPERSAND : '&' ;LPAREN : '(' ;RPAREN : ')' ;LBRACK : '[' ;RBRACK : ']' ;COLON : ':' ;COMMA : ',' ;//DOT : '.' ;EQ : '=' ;NE_COMP : "<>" ;//BNOT : '~' ;SLASH : '/' ;PLUS : '+' ;MINUS : '-' ;STAR : '*' ;GE : ">=" ;GT : ">" ;LE : "<=" ;LT : '<' ;SEMI : ';' ;POUND : '#' ; BINARY_INTEGER : "&b" ('0' | '1' ) + ;OCTAL_INTEGER : "&o" ('0'..'7' ) + ;HEXADECIMAL_INTEGER : "&h" ('0'..'9' | 'a'..'f' ) + ;// Whitespace -- ignoredWS : ( ' ' | '\t' | '\f' ) { _ttype = Token.SKIP; } ;EOL : ( "\r\n" // Evil DOS | '\r' // Macintosh | '\n' // Unix (the right way) ) { newline(); } ;// Single-line commentsSL_COMMENT : '!' (~('\n'|'\r'))* //('\n'|'\r'('\n')?) { $setType(Token.SKIP); //newline(); } ;// character literalsCHAR_LITERAL : '\'' ( (ESCc)=> ESCc | ~'\'' ) '\'' ;// string literalsSTR_CONST : '"'! ( (ESCs)=> ESCs | (ESCqs)=> ESCqs | ~('"'))* '"'! ;protectedESCc : '<' ('0'..'9')+ '>' ;protectedESCs : "<<" ('0'..'9')+ ">>" ;protectedESCqs : '"' '"'! ;// hexadecimal digit (again, note it's protected!)protectedHEX_DIGIT : ('0'..'9'|'a'..'f') ;// a dummy rule to force vocabulary to be all characters (except special// ones that ANTLR uses internally (0 to 2)protectedVOCAB : '\3'..'\377' ;// an identifier. Note that testLiterals is set to true! This means// that after we match the rule, we look in the literals table to see// if it's a literal or really an identiferIDENT options {testLiterals=true;} : ('a'..'z') ('a'..'z'|'0'..'9'|'_'|'.')* ( '$' { if($getText.substring(0,2).toLowerCase().equals("fn")){ _ttype=STR_FN; } else { _ttype=STR_VAR; } } | '%' { if($getText.substring(0,2).toLowerCase().equals("fn")){ _ttype=INT_FN; } else { _ttype=INT_VAR; } } | '#' { if($getText.substring(0,2).toLowerCase().equals("fn")){ _ttype=FLT_FN; } else { _ttype=FLT_VAR; } } | { if($getText.substring(0,2).toLowerCase().equals("fn")){ _ttype=FLT_FN; //} else { // _ttype=FLT_VAR; } } ) ;// a numeric literalINT_CONST {boolean isDecimal=false;} : '.' {_ttype = DOT;} (('0'..'9')+ (EXPONENT)? (FLT_SUFFIX)? { _ttype = FLT_CONST; })? | ( '0' {isDecimal = true;} // special case for just '0' ( ('x') ( // hex // the 'e'|'E' and float suffix stuff look // like hex digits, hence the (...)+ doesn't // know when to stop: ambig. ANTLR resolves // it correctly by matching immediately. It // is therefor ok to hush warning. options { warnWhenFollowAmbig=false; } : HEX_DIGIT )+ | ('0'..'7')+ // octal )? | ('1'..'9') ('0'..'9')* {isDecimal=true;} // non-zero decimal ) ( ('l') // only check to see if it's a float if looks like decimal so far | {isDecimal}? ( '.' ('0'..'9')* (EXPONENT)? (FLT_SUFFIX)? | EXPONENT (FLT_SUFFIX)? | FLT_SUFFIX ) { _ttype = FLT_CONST; } )? ;// a couple protected methods to assist in matching floating point numbersprotectedEXPONENT : ('e') ('+'|'-')? ('0'..'9')+ ;protectedFLT_SUFFIX : 'f'|'d' ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -