📄 pascal.g
字号:
//
// Pascal Parser Grammar
//
// Adapted from,
// Pascal User Manual And Report (Second Edition-1978)
// Kathleen Jensen - Niklaus Wirth
//
// Hakki Dogusan dogusanh@tr-net.net.tr
//
// Import the necessary classes
{
import java.io.*;
}
//-----------------------------------------------------------------------------
// Define a Parser, calling it PascalParser
//-----------------------------------------------------------------------------
class PascalParser extends Parser;
options {
k = 2; // two token lookahead
exportVocab=Pascal; // Call its vocabulary "Pascal"
codeGenMakeSwitchThreshold = 2; // Some optimizations
codeGenBitsetTestThreshold = 3;
defaultErrorHandler = false; // Don't generate parser error handlers
buildAST = false;
}
// Define some methods and variables to use in the generated parser.
{
// Define a main
public static void main(String[] args) {
// Use a try/catch block for parser exceptions
try {
// if we have at least one command-line argument
if (args.length > 0 ) {
System.err.println("Parsing...");
// for each directory/file specified on the command line
for(int i=0; i< args.length;i++)
doFile(new File(args[i])); // parse it
}
else
System.err.println("Usage: java PascalParser <file/directory name>");
}
catch(Exception e) {
System.err.println("exception: "+e);
e.printStackTrace(System.err); // so we can get stack trace
}
}
// This method decides what action to take based on the type of
// file we are looking at
public static void doFile(File f) throws Exception {
// If this is a directory, walk each file/dir in that directory
if (f.isDirectory()) {
String files[] = f.list();
for(int i=0; i < files.length; i++)
doFile(new File(f, files[i]));
}
// otherwise, if this is a Pascal file, parse it!
else if ((f.getName().length()>4) &&
f.getName().substring(f.getName().length()-4).equals(".pas")) {
System.err.println(" "+f.getAbsolutePath());
parseFile(new FileInputStream(f));
}
}
// Here's where we do the real work...
public static void parseFile(InputStream s) throws Exception {
try {
// Create a scanner that reads from the input stream passed to us
PascalLexer lexer = new PascalLexer(s);
// Create a parser that reads from the scanner
PascalParser parser = new PascalParser(lexer);
// start parsing at the program rule
parser.program();
}
catch (Exception e) {
System.err.println("parser exception: "+e);
e.printStackTrace(); // so we can get stack trace
}
}
}
program
: programHeading
block
DOT
;
programHeading
: PROGRAM identifier
LPAREN fileIdentifier ( COMMA fileIdentifier )* RPAREN
SEMI
;
fileIdentifier
: identifier
;
identifier
: IDENT
;
block
: ( labelDeclarationPart
| constantDefinitionPart
| typeDefinitionPart
| variableDeclarationPart
| procedureAndFunctionDeclarationPart
)*
statementPart
;
labelDeclarationPart
: LABEL label ( COMMA label )* SEMI
;
label
: unsignedInteger
;
constantDefinitionPart
: CONST constantDefinition ( SEMI constantDefinition )* SEMI
;
constantDefinition
: identifier EQUAL constant
;
constant
: unsignedNumber
| sign unsignedNumber
| constantIdentifier
| sign constantIdentifier
| string
;
unsignedNumber
: unsignedInteger
| unsignedReal
;
unsignedInteger
: NUM_INT
;
unsignedReal
: NUM_REAL
;
sign
: PLUS | MINUS
;
constantIdentifier
: identifier
;
string
: STRING_LITERAL
;
typeDefinitionPart
: TYPE typeDefinition ( SEMI typeDefinition )* SEMI
;
typeDefinition
: identifier EQUAL type
;
type
: simpleType
| structuredType
| pointerType
;
simpleType
: scalarType
| subrangeType
| typeIdentifier
;
scalarType
: LPAREN identifier ( COMMA identifier )* RPAREN
;
subrangeType
: constant DOTDOT constant
;
typeIdentifier
: identifier
| CHAR
| BOOLEAN
| INTEGER
| REAL
;
structuredType
: ( PACKED
| empty
) unpackedStructuredType
;
unpackedStructuredType
: arrayType
| recordType
| setType
| fileType
;
arrayType
: ARRAY LBRACK indexType ( COMMA indexType )* RBRACK OF
componentType
;
indexType
: simpleType
;
componentType
: type
;
recordType
: RECORD fieldList END
;
fieldList
: fixedPart
( SEMI variantPart
| empty
)
| variantPart
;
fixedPart
: recordSection ( SEMI recordSection )*
;
recordSection
: fieldIdentifier ( COMMA fieldIdentifier )* COLON type
| empty
;
variantPart
: CASE tagField typeIdentifier OF
variant ( SEMI variant )*
;
tagField
: fieldIdentifier COLON
| empty
;
variant
: caseLabelList COLON LPAREN fieldList RPAREN
| empty
;
caseLabelList
: caseLabel ( COMMA caseLabel )*
;
caseLabel
: constant
;
setType
: SET OF baseType
;
baseType
: simpleType
;
fileType
: FILE OF type
;
pointerType
: POINTER typeIdentifier
;
variableDeclarationPart
: VAR variableDeclaration ( SEMI variableDeclaration )* SEMI
;
variableDeclaration
: identifier ( COMMA identifier )* COLON type
;
procedureAndFunctionDeclarationPart
: procedureOrFunctionDeclaration SEMI
;
procedureOrFunctionDeclaration
: procedureDeclaration
| functionDeclaration
;
procedureDeclaration
: procedureHeading
block
;
procedureHeading
: PROCEDURE identifier parameterList SEMI
;
parameterList
: empty
| LPAREN formalParameterSection ( SEMI formalParameterSection )* RPAREN
;
formalParameterSection
: parameterGroup
| VAR parameterGroup
| FUNCTION parameterGroup
| PROCEDURE identifier ( COMMA identifier )*
;
parameterGroup
: identifier ( COMMA identifier )* COLON typeIdentifier
;
functionDeclaration
: functionHeading
block
;
functionHeading
: FUNCTION identifier parameterList COLON resultType SEMI
;
resultType
: typeIdentifier
;
statementPart
: compoundStatement
;
statement
: ( label COLON
| empty
)
unlabelledStatement
;
unlabelledStatement
: simpleStatement
| structuredStatement
;
simpleStatement
: assignmentStatement
| procedureStatement
| gotoStatement
| emptyStatement
;
assignmentStatement
: variable ASSIGN expression
| functionIdentifier ASSIGN expression
;
variable
: entireVariable
| componentVariable
| referencedVariable
;
entireVariable
: variableIdentifier
;
variableIdentifier
: identifier
;
componentVariable
: indexedVariable
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -