All Downloads are FREE. Search and download functionalities are using the official Maven repository.

javacc-7.0.3.grammars.OberonParser.jj Maven / Gradle / Ivy

There is a newer version: 7.0.13
Show newest version
/*
 *               JavaCC source of a
 *               parser for the Oberon-2 Programming Language
 *
 *       Author: James Power,
 *  Affiliation: Dept. of Computer Science, National University of Ireland, 
 *               Maynooth, Co. Kildare, Ireland.
 * Last Revised: 17 November 1998
 *
 *     Based on: "The Programming Language Oberon"
 *               H. Mossenbock, N. Wirth, ETH Zurich, 1992-1996
 *
 * For more information on Oberon see http://www.oberon.ethz.ch/language.html
 */



PARSER_BEGIN(OberonParser)
public final class OberonParser { // Standard parser class setup...

  public static void main(String args[]) { 
    OberonParser parser;
    java.io.InputStream input;

    if (args.length==1) {
      System.out.print(args[args.length-1] + ": ");
      try {
        input = new java.io.FileInputStream(args[args.length-1]);
      } catch (java.io.FileNotFoundException e) {
        System.out.println("File not found.");
        return;
      }
    } else if (args.length==0) {
      System.out.println("Reading from standard input...");
      input = System.in;
    } else {
      System.out.println("Usage: java OberonParser [inputfile]");
      return;
    }
    try {
      parser = new OberonParser(input);
      parser.translation_unit();
      System.out.println("Successful parse!");
    } catch (ParseException e) {
      String msg = e.getMessage();
      msg = msg.substring(0,msg.indexOf("\n"));
      System.out.println("Syntax Error: "+msg);
    }
  }
}
PARSER_END(OberonParser)

/***************************************/
/********** TOKEN DEFINITIONS **********/
/***************************************/

TOKEN_MGR_DECLS :
{
  static int commentNesting;  // Current level of nesting of comments
}


/*** Skip whitespace and comments ***/
SKIP :
{
  " "
| "\t"
| "\n"
| "\r"
| "(*"  { commentNesting=1; } : IN_COMMENT
}
 MORE:
{
  < ~[] >
}
 SKIP:
{
  < "(*" > { commentNesting++; } 
| < "*)" > { commentNesting--; if (commentNesting==0) SwitchTo(DEFAULT); }
}


/*** The keywords ***/
TOKEN :
{
  
| 
| 
| 
| 
| 
| | | | | | | | | | | | | | | | | | | | | | | | | | | | } TOKEN : { < DOTDOT : ".." > } /* The hack: if we see digits followed by "..", trap it here, otherwise * the digits and first dot will be gobbled up to make a REAL below, * and the second dot will give a syntax error */ TOKEN : { < DIGIT_DOT_HACK : ()+ ".." > { // Create the new token and initialise its fields properly Token newTok = new Token(); newTok.kind = DOTDOT; newTok.beginLine = newTok.endLine = matchedToken.endLine; newTok.beginColumn = matchedToken.endColumn-1; newTok.endColumn = matchedToken.endColumn; newTok.image=".."; newTok.next = matchedToken.next; newTok.specialToken = null; // Now fix up matchedToken: matchedToken.kind = INTEGER; matchedToken.endColumn -= 2; matchedToken.image = matchedToken.image.substring(0,matchedToken.image.length()-2); matchedToken.next = newTok; } } /*** Basic constants: numbers, idents, chars and strings ***/ TOKEN : { < #DIGIT : ["0"-"9"] > | < #SCALEFACTOR : ("E" | "D") ("+" | "-")? ()+ > | < #HEXDIGIT : ["0"-"9","A"-"F"] > | < INTEGER : ()+ | ()* "H" > | < REAL : ()+ "." ()* ()? > | < #LETTER : ["A"-"Z","a"-"z"] > | < IDENT : ( | )* > | < CHARACTER : ()* "X" > | < STRING : "\"" (~["\""])* "\"" | "'" (~["'"])* "'" > } /**************************************/ /********** START OF GRAMMAR **********/ /**************************************/ void translation_unit() : {} { Module() } void Module() : {} { ";" (ImportList())? DeclSeq() ( StatementSeq())? "." } void ImportList() : {} { ImportSpec() ("," ImportSpec())* ";" } void ImportSpec() : {} { (":=" )? } void DeclSeq() : {} { ( VarTypeDecl() )* ( ProcedureDecl() )* } void VarTypeDecl() : {} { (ConstDecl() ";")* | (TypeDecl() ";")* | (VarDecl() ";")* } void ConstDecl() : {} { IdentDef() "=" ConstExpr() } void TypeDecl() : {} { IdentDef() "=" Type() } void VarDecl() : {} { IdentList() ":" Type() } void ProcedureDecl() : {} { (ForwardDecl() | ProcDecl()) ";" } void ProcDecl() : {} { (Receiver())? IdentDef() (FormalPars())? ";" DeclSeq() ( StatementSeq())? } void ForwardDecl() : {} { "^" (Receiver())? IdentDef() (FormalPars())? } void FormalPars() : {} { "(" (FPSection() (";" FPSection())*)? ")" (":" Qualident())? } void FPSection() : {} { ()? ("," )* ":" Type() } void Receiver() : {} { "(" ()? ":" ")" } void Type() : {} { Qualident() | (ConstExpr() ("," ConstExpr())*)? Type() | ("("Qualident()")")? FieldList() (";" FieldList())* | Type() | (FormalPars())? } void FieldList() : {} { (IdentList() ":" Type())? } void StatementSeq() : {} { optStatement() (";" optStatement())* } void optStatement() : {} { (Statement())? } void Statement() : {} { Designator() ((":=" Expr()) | Arguments() ) | Expr() StatementSeq() ( Expr() StatementSeq())* ( StatementSeq())? | Expr() Case() ("|" Case())* ( StatementSeq())? | Expr() StatementSeq() | StatementSeq() Expr() | ":=" Expr() Expr() ( ConstExpr())? StatementSeq() | StatementSeq() | Guard() StatementSeq() ("|" Guard() StatementSeq())* ( StatementSeq())? | | (Expr())? } void Case() : {} { (CaseLabels() ("," CaseLabels())* ":" StatementSeq())? } void CaseLabels() : {} { ConstExpr() ( ConstExpr())? } void Guard() : {} { Qualident() ":" Qualident() } void ConstExpr() : {} { Expr() } void Expr() : {} { SimpleExpr() (Relation() SimpleExpr())? } void SimpleExpr() : {} { ("+" | "-")? Term() (AddOp() Term())* } void Term() : {} { Factor() (MulOp() Factor())* } void Factor() : {} { Designator() Arguments() | Number() | | | | Set() | "(" Expr() ")" | "~" Factor() } void Set() : {} { "{" (Element() ("," Element())* )? "}" } void Element() : {} { Expr() ( Expr())? } void Relation() : {} { "=" | "#" | "<" | "<=" | ">" | ">=" | | } void AddOp() : {} { "+" | "-" | } void MulOp() : {} { "*" | "/" |
| | "&" } /* NB: Because Arguments() always appears after Designator(), there * will be a conflict if we get "(" Qualident() ")" - do we consume * this as part of the Designator(), or leave it for the Arguments() * The disambiguation in Designator() chooses the former, so the * semantic phase will have to disentangle this for function calls * with one (qualified) identifier as an argument. */ void Arguments() : {} { ( "(" (ExprList())? ")" )? } void Designator() : {} { (LOOKAHEAD("." | "[" | "^" | ("(" Qualident() ")")) ( "." | "[" ExprList() "]" | "^" | "(" Qualident() ")") )* } void ExprList() : {} { Expr() ("," Expr())* } void IdentList() : {} { IdentDef() ("," IdentDef())* } void Qualident() : {} { // ( ".")? ("." )? } void IdentDef() : {} { ("*" | "-")? } void Number() : {} { | }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy