⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parser.jj

📁 webwork source
💻 JJ
字号:
options {   LOOKAHEAD = 1;   CHOICE_AMBIGUITY_CHECK = 2;   OTHER_AMBIGUITY_CHECK = 1;   STATIC = false; // default is true   DEBUG_PARSER = false; //default is false   DEBUG_LOOKAHEAD = false;   DEBUG_TOKEN_MANAGER = false;   ERROR_REPORTING = true; // default is true (setting to false is supposed to improve performance)   JAVA_UNICODE_ESCAPE = false; // default is false   UNICODE_INPUT = false;   IGNORE_CASE = false;   USER_TOKEN_MANAGER = false;   USER_CHAR_STREAM = false;   BUILD_PARSER = true;   BUILD_TOKEN_MANAGER = true;   SANITY_CHECK = true;   FORCE_LA_CHECK = false;   CACHE_TOKENS = true; //default is false (setting to true improves performance)   OPTIMIZE_TOKEN_MANAGER = true; //default is false (setting to true improves performance)}/* * WebWork, Web Application Framework * * Distributable under Apache license. * See terms of license at opensource.org */PARSER_BEGIN(Parser)package webwork.expr;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import webwork.util.ValueStack;/** *   The WebWork Expression language Parser and Interpreter. * *   @author Maurice C. Parker (maurice@vineyardenterprise.com) *   @version $Revision: 1.21 $ */ public final class Parser{   // Attributes ----------------------------------------------------   private ValueStack valueStack;   private int nestDepth = 0;   protected static Log log = LogFactory.getLog(Parser.class);   // Public --------------------------------------------------------   /**    * Set the value stack    */   public void setValueStack(ValueStack valueStack)   {      this.valueStack = valueStack;   }   // Private -------------------------------------------------------   /**    * This method moves the current token to the next matching    * paren.  This is necessary when you want to end an evaluation    * inside a nested "||" statement early.    *    */   private void consume_remaining_or_tokens() {      Token token;      int nesting = 1;      while (true) {         token = getToken(1);         if (token.kind == LPAREN) nesting++;         if (token.kind == RPAREN) {            nesting--;            if (nesting == 0)               break;         }         token = getNextToken();      }   }   /**    * This method moves the current token to the next matching    * paren.  This is necessary when you want to end an evaluation    * inside a nested "&&" statement early.    *    */   private void consume_remaining_and_tokens() {      Token token;      int nesting = 1;      while (true) {         token = getToken(1);         if (token.kind == OR) break;         if (token.kind == LPAREN) nesting++;         if (token.kind == RPAREN) {            nesting--;            if (nesting == 0)               break;         }         token = getNextToken();      }   }   /**    * determine true or false by comparing the comparison result    * with the operator.    *    * @param   comp  the comparison result    * @param   operatr  the operator    * @return     the boolean result    *    */   private boolean resolve(int comp, Token operatr) {      //log.debug( "comp: " + comp + ", operatr: " + operatr);      if ( comp == 0 )      {         switch (operatr.kind) {            case EQ:            case GE:            case LE:               return true;            default:               return false;         }      }      if ( comp > 0 )      {         switch (operatr.kind) {            case GT:            case GE:            case NE:               return true;            default:               return false;         }      }      switch (operatr.kind) {         case LT:         case LE:         case NE:            return true;      }      return false;   }}PARSER_END(Parser)///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////SKIP :{  " "| "\t"| "\n"| "\r"}TOKEN : /* id */{< ID:(   <STRING_LITERAL> |   ["a"-"z","A"-"Z","0"-"9","_","-",":","@","$",".","/","{","["]   ( ["a"-"z","A"-"Z","0"-"9","_","-",":","'","@","$",".","/","{","}","[","]"] )*   (     "("        ( ( ["a"-"z","A"-"Z","0"-"9"," ","_","-",":","'","@","$",",",".","/","{","}","[","]"] )* |        <STRING_LITERAL> )     ")"   )*   ( ["a"-"z","A"-"Z","0"-"9","_","-",":","@","$",".","/","{","}","[","]"] )*   (     "("        ( ( ["a"-"z","A"-"Z","0"-"9"," ","_","-",":","'","@","$",",",".","/","{","}","[","]"] )* |        <STRING_LITERAL> )     ")"   )*) >}TOKEN : /* string literal */{< STRING_LITERAL: "'" ( ~["'"] )* "'" >}TOKEN : /* parens */{  < LPAREN: "(" > |  < RPAREN: ")" >}TOKEN : /* boolean operators */{  < EQ: "==" > |  < NE: "!=" > |  < GT: ">" > |  < GE: ">=" > |  < LT: "<" > |  < LE: "<=" > |  < AND: "&&" > |  < OR: "||" >}boolean test() : // would be logical_or_expression{   boolean answer;}{   answer=logical_and_expression()   {      if ( answer == true ) {         if ( nestDepth > 0 )            consume_remaining_or_tokens();         return true;      }   }   ( "||" answer=logical_and_expression()      {         if ( answer == true ) {            if ( nestDepth > 0 )               consume_remaining_or_tokens();            return true;         }      }   )*   {      return false;   }}boolean logical_and_expression() :{   boolean answer;}{   answer=comparative_expression()   {      if ( answer == false ) {         if ( nestDepth > 0 )            consume_remaining_and_tokens();         return false;      }   }   ( "&&" answer=comparative_expression()      {         if ( answer == false ) {            if ( nestDepth > 0 )               consume_remaining_and_tokens();            return false;         }      }   )*   {      return true;   }}boolean comparative_expression() :{   Token token;   Object operand1;   Object operand2;   boolean answer = false;}{   (      {         nestDepth++;      }      <LPAREN> answer=test() <RPAREN>      {         nestDepth--;      }   |      // Null test      "!" operand1=findValue()      {         if ( operand1 == null )            return true;         else            return false;      }   |      (         // Not null test         operand1=findValue()         {            if ( operand1 != null )               answer = true;            else               answer =  false;         }         // Normal comparison         (  ( token=<EQ> |              token=<NE> |              token=<GT> |              token=<GE> |              token=<LT> |              token=<LE> ) operand2 = findValue()            {               // We resolve nulls by hand               if ( operand1 == null || operand2 == null )               {                  int comp = -1; // less than                  if ( operand1 == null && operand2 == null ) // equal to                  {                     comp = 0;                  }                  else if ( operand2 == null ) // greater than                  {                     comp = 1;                  }                  return resolve(comp, token);               }               if ( operand1 instanceof Number && operand2 instanceof Number ) {                  double number1 = ((Number)operand1).doubleValue();                  double number2 = ((Number)operand2).doubleValue();                  int comp = -1; // less than                  if ( number1 > number2 ) {                     comp = 1;  // greater than                  } else if ( number1 == number2 ) {                     long longBits1 = Double.doubleToLongBits(number1);                     long longBits2 = Double.doubleToLongBits(number2);                     if ( longBits1 > longBits2 ) {                        comp = 1;                     } else if ( longBits1 == longBits2 ) {                        comp = 0;                     }                  }                  return resolve(comp, token);               }              // If operands are of the same type, do a direct comparison              if ( operand1.getClass().equals(operand2.getClass()) ) {                  if ( operand1 instanceof Comparable ) {                      int comp = ((Comparable)operand1).compareTo(operand2);                      return resolve(comp, token);                  }              }              // If the operands aren't the same type or aren't comparible, then              // convert them to strings and do a comparison              // Mo: I think that this could lead to some difficult to predict or unpredictable behavior              operand1 = operand1.toString();              operand2 = operand2.toString();              int comp = ((Comparable)operand1).compareTo(operand2);              return resolve(comp, token);            } )?         )   )   {      return answer;   }}Object findValue() :{   Token token;}{   /* Constants */   token=<ID>   {      return valueStack.findValue(token.image);   }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -