📄 pascal.g
字号:
| fieldDesignator
| fileBuffer
;
indexedVariable
: arrayVariable LBRACK expression ( COMMA expression)* RBRACK
;
arrayVariable
: identifier
;
fieldDesignator
: recordVariable DOT fieldIdentifier
;
recordVariable
: identifier
;
fieldIdentifier
: identifier
;
fileBuffer
: fileVariable POINTER
;
fileVariable
: identifier
;
referencedVariable
: pointerVariable POINTER
;
pointerVariable
: identifier
;
expression
: simpleExpression
( empty
| relationalOperator simpleExpression
)
;
relationalOperator
: EQUAL | NOT_EQUAL | LT | LE | GE | GT | IN
;
simpleExpression
: ( sign
| empty
)
term ( addingOperator term )*
;
addingOperator
: PLUS | MINUS | OR
;
term
: factor ( multiplyingOperator factor )*
;
multiplyingOperator
: STAR | SLASH | DIV | MOD | AND
;
factor
: variable
| unsignedConstant
| LPAREN expression RPAREN
| functionDesignator
| set
| NOT factor
;
unsignedConstant
: unsignedNumber
| string
| constantIdentifier
| NIL
;
functionDesignator
: functionIdentifier
( LPAREN actualParameter ( COMMA actualParameter ) * RPAREN
| empty
)
;
functionIdentifier
: identifier
;
set
: LBRACK elementList RBRACK
;
elementList
: element ( COMMA element )*
| empty
;
element
: expression
( DOTDOT expression
| empty
)
;
procedureStatement
: procedureIdentifier
( LPAREN actualParameter ( COMMA actualParameter )* RPAREN
| empty
)
;
procedureIdentifier
: identifier
;
actualParameter
: expression
| variable
| procedureIdentifier
| functionIdentifier
;
gotoStatement
: GOTO label
;
emptyStatement
: empty
;
empty
: /* empty */
;
structuredStatement
: compoundStatement
| conditionalStatement
| repetetiveStatement
| withStatement
;
compoundStatement
: BEGIN
statement ( SEMI statement )*
END
;
conditionalStatement
: ifStatement
| caseStatement
;
ifStatement
: IF expression THEN statement
( ELSE statement
| empty
)
;
caseStatement
: CASE expression OF
caseListElement ( SEMI caseListElement )*
END
;
caseListElement
: caseLabelList COLON statement
| empty
;
repetetiveStatement
: whileStatement
| repeatStatement
| forStatement
;
whileStatement
: WHILE expression DO
statement
;
repeatStatement
: REPEAT
statement ( SEMI statement )*
UNTIL expression
;
forStatement
: FOR controlVariable ASSIGN forList DO
statement
;
forList
: initialValue ( TO | DOWNTO ) finalValue
;
controlVariable
: identifier
;
initialValue
: expression
;
finalValue
: expression
;
withStatement
: WITH recordVariableList DO
statement
;
recordVariableList
: recordVariable ( COMMA recordVariable )*
;
//----------------------------------------------------------------------------
// The Pascal scanner
//----------------------------------------------------------------------------
class PascalLexer extends Lexer;
options {
charVocabulary = '\0'..'\377';
exportVocab = Pascal; // call the vocabulary "Pascal"
testLiterals = false; // don't automatically test for literals
k = 4; // four characters of lookahead
caseSensitive = false;
caseSensitiveLiterals = false;
}
tokens {
AND = "and" ;
ARRAY = "array" ;
BEGIN = "begin" ;
BOOLEAN = "boolean" ;
CASE = "case" ;
CHAR = "char" ;
CONST = "const" ;
DIV = "div" ;
DO = "do" ;
DOWNTO = "downto" ;
ELSE = "else" ;
END = "end" ;
FILE = "file" ;
FOR = "for" ;
FUNCTION = "function" ;
GOTO = "goto" ;
IF = "if" ;
IN = "in" ;
INTEGER = "integer" ;
LABEL = "label" ;
MOD = "mod" ;
NIL = "nil" ;
NOT = "not" ;
OF = "of" ;
OR = "or" ;
PACKED = "packed" ;
PROCEDURE = "procedure" ;
PROGRAM = "program" ;
REAL = "real" ;
RECORD = "record" ;
REPEAT = "repeat" ;
SET = "set" ;
THEN = "then" ;
TO = "to" ;
TYPE = "type" ;
UNTIL = "until" ;
VAR = "var" ;
WHILE = "while" ;
WITH = "with" ;
}
//----------------------------------------------------------------------------
// OPERATORS
//----------------------------------------------------------------------------
PLUS : '+' ;
MINUS : '-' ;
STAR : '*' ;
SLASH : '/' ;
ASSIGN : ":=" ;
COMMA : ',' ;
SEMI : ';' ;
COLON : ':' ;
EQUAL : '=' ;
NOT_EQUAL : "<>" ;
LT : '<' ;
LE : "<=" ;
GE : ">=" ;
GT : '>' ;
LPAREN : '(' ;
RPAREN : ')' ;
LBRACK : '[' ;
RBRACK : ']' ;
POINTER : '^' ;
//DOT : '.' ;
//DOTDOT : ".." ;
// Whitespace -- ignored
WS : ( ' '
| '\t'
| '\f'
// handle newlines
| ( "\r\n" // Evil DOS
| '\r' // Macintosh
| '\n' // Unix (the right way)
)
{ newline(); }
)
{ _ttype = Token.SKIP; }
;
COMMENT_1
: "(*"
( options { generateAmbigWarnings=false; }
: { LA(2) != ')' }? '*'
| '\r' '\n' {newline();}
| '\r' {newline();}
| '\n' {newline();}
| ~('*' | '\n' | '\r')
)*
"*)"
{$setType(Token.SKIP);}
;
COMMENT_2
: '{'
( options {generateAmbigWarnings=false;}
: '\r' '\n' {newline();}
| '\r' {newline();}
| '\n' {newline();}
| ~('}' | '\n' | '\r')
)*
'}'
{$setType(Token.SKIP);}
;
// 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 identifer
IDENT
options {testLiterals=true;}
: ('a'..'z') ('a'..'z'|'0'..'9')*
;
// string literals
STRING_LITERAL
: '\'' ("\'\'" | ~('\''))+ '\''
;
// a numeric literal
NUM_INT
{boolean isDecimal=false;}
: ".." {_ttype = DOTDOT;}
| '.' {_ttype = DOT;}
(('0'..'9')+ (EXPONENT)? { _ttype = NUM_REAL; })?
| ( '0' {isDecimal = true;} // special case for just '0'
| ('1'..'9') ('0'..'9')* {isDecimal=true;} // non-zero decimal
)
// only check to see if it's a float if looks like decimal so far
( { LA(2)!='.' && LA(3)!='.' && isDecimal}?
( '.' ('0'..'9')* (EXPONENT)?
| EXPONENT
)
{ _ttype = NUM_REAL; }
)?
;
// a couple protected methods to assist in matching floating point numbers
protected
EXPONENT
: ('e') ('+'|'-')? ('0'..'9')+
;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -