pascal.g
上传用户:afrynkmhm
上传日期:2007-01-06
资源大小:1262k
文件大小:15k
源码类别:

编译器/解释器

开发平台:

Others

  1. //
  2. // Pascal Parser Grammar
  3. //
  4. // Adapted from,
  5. // Pascal User Manual And Report (Second Edition-1978)
  6. // Kathleen Jensen - Niklaus Wirth
  7. //
  8. // Hakki Dogusan dogusanh@tr-net.net.tr
  9. //
  10. // Import the necessary classes
  11. {
  12.   import java.io.*;
  13. }
  14. //-----------------------------------------------------------------------------
  15. // Define a Parser, calling it PascalParser
  16. //-----------------------------------------------------------------------------
  17. class PascalParser extends Parser;
  18. options {
  19.   k = 2;                           // two token lookahead
  20.   exportVocab=Pascal;              // Call its vocabulary "Pascal"
  21.   codeGenMakeSwitchThreshold = 2;  // Some optimizations
  22.   codeGenBitsetTestThreshold = 3;
  23.   defaultErrorHandler = false;     // Don't generate parser error handlers
  24.   buildAST = false;
  25. }
  26. // Define some methods and variables to use in the generated parser.
  27. {
  28.   // Define a main
  29.   public static void main(String[] args) {
  30.     // Use a try/catch block for parser exceptions
  31.     try {
  32.       // if we have at least one command-line argument
  33.       if (args.length > 0 ) {
  34.         System.err.println("Parsing...");
  35.         // for each directory/file specified on the command line
  36.         for(int i=0; i< args.length;i++)
  37.           doFile(new File(args[i])); // parse it
  38.       }
  39.       else
  40.         System.err.println("Usage: java PascalParser <file/directory name>");
  41.     }
  42.     catch(Exception e) {
  43.       System.err.println("exception: "+e);
  44.       e.printStackTrace(System.err);   // so we can get stack trace
  45.     }
  46.   }
  47.   // This method decides what action to take based on the type of
  48.   //   file we are looking at
  49.   public static void doFile(File f) throws Exception {
  50.     // If this is a directory, walk each file/dir in that directory
  51.     if (f.isDirectory()) {
  52.       String files[] = f.list();
  53.       for(int i=0; i < files.length; i++)
  54.         doFile(new File(f, files[i]));
  55.     }
  56.     // otherwise, if this is a Pascal file, parse it!
  57.     else if ((f.getName().length()>4) &&
  58.              f.getName().substring(f.getName().length()-4).equals(".pas")) {
  59.       System.err.println("   "+f.getAbsolutePath());
  60.       parseFile(new FileInputStream(f));
  61.     }
  62.   }
  63.   // Here's where we do the real work...
  64.   public static void parseFile(InputStream s) throws Exception {
  65.     try {
  66.       // Create a scanner that reads from the input stream passed to us
  67.       PascalLexer lexer = new PascalLexer(s);
  68.       // Create a parser that reads from the scanner
  69.       PascalParser parser = new PascalParser(lexer);
  70.       // start parsing at the program rule
  71. parser.program(); 
  72.     }
  73.     catch (Exception e) {
  74.       System.err.println("parser exception: "+e);
  75.       e.printStackTrace();   // so we can get stack trace
  76.     }
  77.   }
  78. }
  79. program
  80. : programHeading
  81.       block
  82.       DOT
  83. ;
  84. programHeading
  85.     : PROGRAM identifier
  86.       LPAREN fileIdentifier ( COMMA fileIdentifier )* RPAREN
  87.       SEMI
  88. ;
  89. fileIdentifier
  90.     : identifier
  91.     ;
  92. identifier
  93.     : IDENT
  94.     ;
  95. block
  96.     : ( labelDeclarationPart
  97.       | constantDefinitionPart
  98.       | typeDefinitionPart
  99.       | variableDeclarationPart
  100.       | procedureAndFunctionDeclarationPart
  101.       )*
  102.       statementPart
  103.     ;
  104. labelDeclarationPart
  105.     : LABEL label ( COMMA label )* SEMI
  106.     ;
  107. label
  108.     : unsignedInteger
  109.     ;
  110. constantDefinitionPart
  111.     : CONST constantDefinition ( SEMI constantDefinition )* SEMI
  112.     ;
  113. constantDefinition
  114.     : identifier EQUAL constant
  115.     ;
  116. constant
  117.     : unsignedNumber
  118.     | sign unsignedNumber
  119.     | constantIdentifier
  120.     | sign constantIdentifier
  121.     | string
  122.     ;
  123. unsignedNumber
  124.     : unsignedInteger
  125.     | unsignedReal
  126.     ;
  127. unsignedInteger
  128.     : NUM_INT
  129.     ;
  130. unsignedReal
  131.     : NUM_REAL
  132.     ;
  133. sign
  134.     : PLUS | MINUS
  135.     ;
  136. constantIdentifier
  137.     : identifier
  138.     ;
  139. string
  140.     : STRING_LITERAL
  141.     ;
  142. typeDefinitionPart
  143.     : TYPE typeDefinition ( SEMI typeDefinition )* SEMI
  144.     ;
  145. typeDefinition
  146.     : identifier EQUAL type
  147.     ;
  148. type
  149.     : simpleType
  150.     | structuredType
  151.     | pointerType
  152.     ;
  153. simpleType
  154.     : scalarType
  155.     | subrangeType
  156.     | typeIdentifier
  157.     ;
  158. scalarType
  159.     : LPAREN identifier ( COMMA identifier )* RPAREN
  160.     ;
  161. subrangeType
  162.     : constant DOTDOT constant
  163.     ;
  164. typeIdentifier
  165.     : identifier
  166.     | CHAR
  167.     | BOOLEAN
  168.     | INTEGER
  169.     | REAL
  170.     ;
  171. structuredType
  172.     : ( PACKED
  173.       | empty
  174.       ) unpackedStructuredType
  175.     ;
  176. unpackedStructuredType
  177.     : arrayType
  178.     | recordType
  179.     | setType
  180.     | fileType
  181.     ;
  182. arrayType
  183.     : ARRAY LBRACK indexType ( COMMA indexType )* RBRACK OF
  184.       componentType
  185.     ;
  186. indexType
  187.     : simpleType
  188.     ;
  189. componentType
  190.     : type
  191.     ;
  192. recordType
  193.     : RECORD fieldList END
  194.     ;
  195. fieldList
  196.     : fixedPart
  197.         ( SEMI variantPart
  198.         | empty
  199.         )
  200.     | variantPart
  201.     ;
  202. fixedPart
  203.     : recordSection ( SEMI recordSection )*
  204.     ;
  205. recordSection
  206.     : fieldIdentifier ( COMMA fieldIdentifier )* COLON type
  207.     | empty
  208.     ;
  209. variantPart
  210.     : CASE tagField typeIdentifier OF
  211.       variant ( SEMI variant )*
  212.     ;
  213. tagField
  214.     : fieldIdentifier COLON
  215.     | empty
  216.     ;
  217. variant
  218.     : caseLabelList COLON LPAREN fieldList RPAREN
  219.     | empty
  220.     ;
  221. caseLabelList
  222.     : caseLabel ( COMMA caseLabel )*
  223.     ;
  224. caseLabel
  225.     : constant
  226.     ;
  227. setType
  228.     : SET OF baseType
  229.     ;
  230. baseType
  231.     : simpleType
  232.     ;
  233. fileType
  234.     : FILE OF type
  235.     ;
  236. pointerType
  237.     : POINTER typeIdentifier
  238.     ;
  239. variableDeclarationPart
  240.     : VAR variableDeclaration ( SEMI variableDeclaration )* SEMI
  241.     ;
  242. variableDeclaration
  243.     : identifier ( COMMA identifier )* COLON type
  244.     ;
  245. procedureAndFunctionDeclarationPart
  246.     : procedureOrFunctionDeclaration SEMI
  247.     ;
  248. procedureOrFunctionDeclaration
  249.     : procedureDeclaration
  250.     | functionDeclaration
  251.     ;
  252. procedureDeclaration
  253.     : procedureHeading
  254.       block
  255.     ;
  256. procedureHeading
  257.     : PROCEDURE identifier parameterList SEMI
  258.     ;
  259. parameterList
  260.     : empty
  261.     | LPAREN formalParameterSection ( SEMI formalParameterSection )* RPAREN
  262.     ;
  263. formalParameterSection
  264.     : parameterGroup
  265.     | VAR parameterGroup
  266.     | FUNCTION parameterGroup
  267.     | PROCEDURE identifier ( COMMA identifier )*
  268.     ;
  269. parameterGroup
  270.     : identifier ( COMMA identifier )* COLON typeIdentifier
  271.     ;
  272. functionDeclaration
  273.     : functionHeading
  274.       block
  275.     ;
  276. functionHeading
  277.     : FUNCTION identifier  parameterList  COLON resultType SEMI
  278.     ;
  279. resultType
  280.     : typeIdentifier
  281.     ;
  282. statementPart
  283.     : compoundStatement
  284.     ;
  285. statement
  286.     : ( label COLON
  287.       | empty
  288.       )
  289.       unlabelledStatement
  290.     ;
  291. unlabelledStatement
  292.     : simpleStatement
  293.     | structuredStatement
  294.     ;
  295. simpleStatement
  296.     : assignmentStatement
  297.     | procedureStatement
  298.     | gotoStatement
  299.     | emptyStatement
  300.     ;
  301. assignmentStatement
  302.     : variable ASSIGN expression
  303.     | functionIdentifier ASSIGN expression
  304.     ;
  305. variable
  306.     : entireVariable
  307.     | componentVariable
  308.     | referencedVariable
  309.     ;
  310. entireVariable
  311.     : variableIdentifier
  312.     ;
  313. variableIdentifier
  314.     : identifier
  315.     ;
  316. componentVariable
  317.     : indexedVariable
  318.     | fieldDesignator
  319.     | fileBuffer
  320.     ;
  321. indexedVariable
  322.     : arrayVariable LBRACK expression ( COMMA expression)* RBRACK
  323.     ;
  324. arrayVariable
  325.     : identifier
  326.     ;
  327. fieldDesignator
  328.     : recordVariable DOT fieldIdentifier
  329.     ;
  330. recordVariable
  331.     : identifier
  332.     ;
  333. fieldIdentifier
  334.     : identifier
  335.     ;
  336. fileBuffer
  337.     : fileVariable POINTER
  338.     ;
  339. fileVariable
  340.     : identifier
  341.     ;
  342. referencedVariable
  343.     : pointerVariable POINTER
  344.     ;
  345. pointerVariable
  346.     : identifier
  347.     ;
  348. expression
  349.     : simpleExpression
  350.       ( empty
  351.       | relationalOperator simpleExpression
  352.       )
  353.     ;
  354. relationalOperator
  355.     : EQUAL | NOT_EQUAL | LT | LE | GE | GT | IN
  356.     ;
  357. simpleExpression
  358.     : ( sign
  359.       | empty
  360.       )
  361.       term ( addingOperator term )*
  362.     ;
  363. addingOperator
  364.     : PLUS | MINUS | OR
  365.     ;
  366. term
  367.     : factor ( multiplyingOperator factor )*
  368.     ;
  369. multiplyingOperator
  370.     : STAR | SLASH | DIV | MOD | AND
  371.     ;
  372. factor
  373.     : variable
  374.     | unsignedConstant
  375.     | LPAREN expression RPAREN
  376.     | functionDesignator
  377.     | set
  378.     | NOT factor
  379.     ;
  380. unsignedConstant
  381.     : unsignedNumber
  382.     | string
  383.     | constantIdentifier
  384.     | NIL
  385.     ;
  386. functionDesignator
  387.     : functionIdentifier
  388.         ( LPAREN actualParameter ( COMMA actualParameter ) * RPAREN
  389.         | empty
  390.         )
  391.     ;
  392. functionIdentifier
  393.     : identifier
  394.     ;
  395. set
  396.     : LBRACK elementList RBRACK
  397.     ;
  398. elementList
  399.     : element ( COMMA element )*
  400.     | empty
  401.     ;
  402. element
  403.     : expression
  404.         ( DOTDOT expression
  405.         | empty
  406.         )
  407.     ;
  408. procedureStatement
  409.     : procedureIdentifier
  410.         ( LPAREN actualParameter ( COMMA actualParameter )* RPAREN
  411.         | empty
  412.         )
  413.     ;
  414. procedureIdentifier
  415.     : identifier
  416.     ;
  417. actualParameter
  418.     : expression
  419.     | variable
  420.     | procedureIdentifier
  421.     | functionIdentifier
  422.     ;
  423. gotoStatement
  424.     : GOTO label
  425.     ;
  426. emptyStatement
  427.     : empty
  428.     ;
  429. empty
  430.     : /* empty */
  431.     ;
  432. structuredStatement
  433.     : compoundStatement
  434.     | conditionalStatement
  435.     | repetetiveStatement
  436.     | withStatement
  437.     ;
  438. compoundStatement
  439.     : BEGIN
  440.         statement ( SEMI statement )*
  441.       END
  442.     ;
  443. conditionalStatement
  444.     : ifStatement
  445.     | caseStatement
  446.     ;
  447. ifStatement
  448.     : IF expression THEN statement
  449.       ( ELSE statement
  450.       | empty
  451.       )
  452.     ;
  453. caseStatement
  454.     : CASE expression OF
  455.         caseListElement ( SEMI caseListElement )*
  456.       END
  457.     ;
  458. caseListElement
  459.     : caseLabelList COLON statement
  460.     | empty
  461.     ;
  462. repetetiveStatement
  463.     : whileStatement
  464.     | repeatStatement
  465.     | forStatement
  466.     ;
  467. whileStatement
  468.     : WHILE expression DO
  469.         statement
  470.     ;
  471. repeatStatement
  472.     : REPEAT
  473.         statement ( SEMI statement )*
  474.       UNTIL expression
  475.     ;
  476. forStatement
  477.     : FOR controlVariable ASSIGN forList DO
  478.         statement
  479.     ;
  480. forList
  481.     : initialValue ( TO | DOWNTO ) finalValue
  482.     ;
  483. controlVariable
  484.     : identifier
  485.     ;
  486. initialValue
  487.     : expression
  488.     ;
  489. finalValue
  490.     : expression
  491.     ;
  492. withStatement
  493.     : WITH recordVariableList DO
  494.         statement
  495.     ;
  496. recordVariableList
  497.     : recordVariable ( COMMA recordVariable )*
  498.     ;
  499. //----------------------------------------------------------------------------
  500. // The Pascal scanner
  501. //----------------------------------------------------------------------------
  502. class PascalLexer extends Lexer;
  503. options {
  504.   charVocabulary = ''..'377';
  505.   exportVocab = Pascal;   // call the vocabulary "Pascal"
  506.   testLiterals = false;   // don't automatically test for literals
  507.   k = 4;                  // four characters of lookahead
  508.   caseSensitive = false;
  509.   caseSensitiveLiterals = false;
  510. }
  511. tokens {
  512.   AND              = "and"             ;
  513.   ARRAY            = "array"           ;
  514.   BEGIN            = "begin"           ;
  515.   BOOLEAN          = "boolean"         ;
  516.   CASE             = "case"            ;
  517.   CHAR             = "char"            ;
  518.   CONST            = "const"           ;
  519.   DIV              = "div"             ;
  520.   DO               = "do"              ;
  521.   DOWNTO           = "downto"          ;
  522.   ELSE             = "else"            ;
  523.   END              = "end"             ;
  524.   FILE             = "file"            ;
  525.   FOR              = "for"             ;
  526.   FUNCTION         = "function"        ;
  527.   GOTO             = "goto"            ;
  528.   IF               = "if"              ;
  529.   IN               = "in"              ;
  530.   INTEGER          = "integer"         ;
  531.   LABEL            = "label"           ;
  532.   MOD              = "mod"             ;
  533.   NIL              = "nil"             ;
  534.   NOT              = "not"             ;
  535.   OF               = "of"              ;
  536.   OR               = "or"              ;
  537.   PACKED           = "packed"          ;
  538.   PROCEDURE        = "procedure"       ;
  539.   PROGRAM          = "program"         ;
  540.   REAL             = "real"            ;
  541.   RECORD           = "record"          ;
  542.   REPEAT           = "repeat"          ;
  543.   SET              = "set"             ;
  544.   THEN             = "then"            ;
  545.   TO               = "to"              ;
  546.   TYPE             = "type"            ;
  547.   UNTIL            = "until"           ;
  548.   VAR              = "var"             ;
  549.   WHILE            = "while"           ;
  550.   WITH             = "with"            ;
  551. }
  552. //----------------------------------------------------------------------------
  553. // OPERATORS
  554. //----------------------------------------------------------------------------
  555. PLUS            : '+'   ;
  556. MINUS           : '-'   ;
  557. STAR            : '*'   ;
  558. SLASH           : '/'   ;
  559. ASSIGN          : ":="  ;
  560. COMMA           : ','   ;
  561. SEMI            : ';'   ;
  562. COLON           : ':'   ;
  563. EQUAL           : '='   ;
  564. NOT_EQUAL       : "<>"  ;
  565. LT              : '<'   ;
  566. LE              : "<="  ;
  567. GE              : ">="  ;
  568. GT              : '>'   ;
  569. LPAREN          : '('   ;
  570. RPAREN          : ')'   ;
  571. LBRACK          : '['   ;
  572. RBRACK          : ']'   ;
  573. POINTER         : '^'   ;
  574. //DOT             : '.'   ;
  575. //DOTDOT          : ".."  ;
  576. // Whitespace -- ignored
  577. WS      : ( ' '
  578. | 't'
  579. | 'f'
  580. // handle newlines
  581. | ( "rn"  // Evil DOS
  582. | 'r'    // Macintosh
  583. | 'n'    // Unix (the right way)
  584. )
  585. { newline(); }
  586. )
  587. { _ttype = Token.SKIP; }
  588. ;
  589. COMMENT_1
  590.         : "(*"
  591.    ( options { generateAmbigWarnings=false; }
  592.    : { LA(2) != ')' }? '*'
  593.    | 'r' 'n' {newline();}
  594.    | 'r' {newline();}
  595.    | 'n' {newline();}
  596.            |   ~('*' | 'n' | 'r')
  597.    )*
  598.           "*)"
  599. {$setType(Token.SKIP);}
  600. ;
  601. COMMENT_2
  602.         :  '{'
  603.     ( options {generateAmbigWarnings=false;}
  604.             :   'r' 'n'       {newline();}
  605.     | 'r' {newline();}
  606.     | 'n' {newline();}
  607.             |   ~('}' | 'n' | 'r')
  608.     )*
  609.            '}'
  610. {$setType(Token.SKIP);}
  611. ;
  612. // an identifier.  Note that testLiterals is set to true!  This means
  613. // that after we match the rule, we look in the literals table to see
  614. // if it's a literal or really an identifer
  615. IDENT
  616. options {testLiterals=true;}
  617. : ('a'..'z') ('a'..'z'|'0'..'9')*
  618. ;
  619. // string literals
  620. STRING_LITERAL
  621. : ''' ("''" | ~('''))+ '''
  622. ;
  623. // a numeric literal
  624. NUM_INT
  625. {boolean isDecimal=false;}
  626. : ".." {_ttype = DOTDOT;}
  627.     |   '.'  {_ttype = DOT;}
  628. (('0'..'9')+ (EXPONENT)? { _ttype = NUM_REAL; })?
  629. | ( '0' {isDecimal = true;} // special case for just '0'
  630. | ('1'..'9') ('0'..'9')*  {isDecimal=true;} // non-zero decimal
  631. )
  632. // only check to see if it's a float if looks like decimal so far
  633. ( { LA(2)!='.' && LA(3)!='.' && isDecimal}?
  634. ( '.' ('0'..'9')* (EXPONENT)?
  635. | EXPONENT
  636. )
  637. { _ttype = NUM_REAL; }
  638. )?
  639. ;
  640. // a couple protected methods to assist in matching floating point numbers
  641. protected
  642. EXPONENT
  643. : ('e') ('+'|'-')? ('0'..'9')+
  644. ;