/*
* $Id$
*
* Copyright (C) 2003-2015 JNode.org
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; If not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package org.jnode.shell.bjorne;
import org.jnode.shell.CommandLine;
public class BjorneToken extends CommandLine.Token {
public static final int TOK_END_OF_STREAM = 1;
public static final long TOK_END_OF_STREAM_BIT = (1 << TOK_END_OF_STREAM);
public static final int TOK_END_OF_LINE = 2;
public static final long TOK_END_OF_LINE_BIT = (1 << TOK_END_OF_LINE);
// See The Open Group Base Specifications Issue 6
// IEEE Std 1003.1, 2004 Edition
// Chapter 2 Section 2.10.2
public static final int TOK_SEMI = 3; // ;
public static final long TOK_SEMI_BIT = (1L << TOK_SEMI);
public static final int TOK_AMP = 4; // &
public static final long TOK_AMP_BIT = (1L << TOK_AMP);
public static final int TOK_BAR = 5; // |
public static final long TOK_BAR_BIT = (1L << TOK_BAR);
public static final int TOK_LESS = 6; // <
public static final long TOK_LESS_BIT = (1L << TOK_LESS);
public static final int TOK_GREAT = 7; // >
public static final long TOK_GREAT_BIT = (1L << TOK_GREAT);
public static final int TOK_LPAREN = 8; // (
public static final long TOK_LPAREN_BIT = (1L << TOK_LPAREN);
public static final int TOK_RPAREN = 9; // )
public static final long TOK_RPAREN_BIT = (1L << TOK_RPAREN);
public static final int TOK_LBRACE = 10; // { reserved word
public static final long TOK_LBRACE_BIT = (1L << TOK_LBRACE);
public static final int TOK_RBRACE = 11; // } reserved word
public static final long TOK_RBRACE_BIT = (1L << TOK_RBRACE);
public static final int TOK_BANG = 12; // ! reserved word
public static final long TOK_BANG_BIT = (1L << TOK_BANG);
public static final int TOK_AND_IF = 13; // &&
public static final long TOK_AND_IF_BIT = (1L << TOK_AND_IF);
public static final int TOK_OR_IF = 14; // ||
public static final long TOK_OR_IF_BIT = (1L << TOK_OR_IF);
public static final int TOK_DSEMI = 15; // ;;
public static final long TOK_DSEMI_BIT = (1L << TOK_DSEMI);
public static final int TOK_DLESS = 16; // <<
public static final long TOK_DLESS_BIT = (1L << TOK_DLESS);
public static final int TOK_DGREAT = 17; // >>
public static final long TOK_DGREAT_BIT = (1L << TOK_DGREAT);
public static final int TOK_LESSAND = 18; // <&
public static final long TOK_LESSAND_BIT = (1L << TOK_LESSAND);
public static final int TOK_GREATAND = 19; // >&
public static final long TOK_GREATAND_BIT = (1L << TOK_GREATAND);
public static final int TOK_LESSGREAT = 20; // <>
public static final long TOK_LESSGREAT_BIT = (1L << TOK_LESSGREAT);
public static final int TOK_DLESSDASH = 21; // <<-
public static final long TOK_DLESSDASH_BIT = (1L << TOK_DLESSDASH);
public static final int TOK_CLOBBER = 22; // >|
public static final long TOK_CLOBBER_BIT = (1L << TOK_CLOBBER);
public static final int TOK_WORD = 23;
public static final long TOK_WORD_BIT = (1L << TOK_WORD);
public static final int TOK_NAME = 24;
public static final long TOK_NAME_BIT = (1L << TOK_NAME);
public static final int TOK_ASSIGNMENT = 25;
public static final long TOK_ASSIGNMENT_BIT = (1L << TOK_ASSIGNMENT);
public static final int TOK_IO_NUMBER = 26;
public static final long TOK_IO_NUMBER_BIT = (1L << TOK_IO_NUMBER);
public static final int TOK_IF = 27;
public static final long TOK_IF_BIT = (1L << TOK_IF);
public static final int TOK_THEN = 28;
public static final long TOK_THEN_BIT = (1L << TOK_THEN);
public static final int TOK_ELSE = 29;
public static final long TOK_ELSE_BIT = (1L << TOK_ELSE);
public static final int TOK_ELIF = 30;
public static final long TOK_ELIF_BIT = (1L << TOK_ELIF);
public static final int TOK_FI = 31;
public static final long TOK_FI_BIT = (1L << TOK_FI);
public static final int TOK_DO = 32;
public static final long TOK_DO_BIT = (1L << TOK_DO);
public static final int TOK_DONE = 33;
public static final long TOK_DONE_BIT = (1L << TOK_DONE);
public static final int TOK_CASE = 34;
public static final long TOK_CASE_BIT = (1L << TOK_CASE);
public static final int TOK_ESAC = 35;
public static final long TOK_ESAC_BIT = (1L << TOK_ESAC);
public static final int TOK_WHILE = 36;
public static final long TOK_WHILE_BIT = (1L << TOK_WHILE);
public static final int TOK_UNTIL = 37;
public static final long TOK_UNTIL_BIT = (1L << TOK_UNTIL);
public static final int TOK_FOR = 38;
public static final long TOK_FOR_BIT = (1L << TOK_FOR);
public static final int TOK_IN = 39;
public static final long TOK_IN_BIT = (1L << TOK_IN);
// The following token types specialize the 'word' and 'name' types.
// A token won't be assigned one of these types, but the corresponding
// bits are included in the expectedSet bitsets to tell the completer
// what kind of completion to use.
public static final int TOK_COMMAND_NAME = 40;
public static final long TOK_COMMAND_NAME_BITS = (1L << TOK_COMMAND_NAME) + TOK_WORD_BIT;
public static final int TOK_COMMAND_WORD = 41;
public static final long TOK_COMMAND_WORD_BITS = (1L << TOK_COMMAND_WORD) + TOK_WORD_BIT;
public static final int TOK_FUNCTION_NAME = 42;
public static final long TOK_FUNCTION_NAME_BITS = (1L << TOK_FUNCTION_NAME) + TOK_NAME_BIT;
public static final int TOK_HERE_END = 43;
public static final long TOK_HERE_END_BITS = (1L << TOK_HERE_END) + TOK_WORD_BIT;
public static final int TOK_FOR_NAME = 44;
public static final long TOK_FOR_NAME_BITS = (1L << TOK_FOR_NAME) + TOK_NAME_BIT;
// }
public static final int TOK_FOR_WORD = 45;
public static final long TOK_FOR_WORD_BITS = (1L << TOK_FOR_WORD) + TOK_WORD_BIT;
public static final int TOK_PATTERN = 46;
public static final long TOK_PATTERN_BITS = (1L << TOK_PATTERN) + TOK_WORD_BIT;
public static final int TOK_FILE_NAME = 47;
public static final long TOK_FILE_NAME_BITS = (1L << TOK_FILE_NAME) + TOK_WORD_BIT;
public static final int TOK_CASE_WORD = 48;
public static final long TOK_CASE_WORD_BITS = (1L << TOK_CASE_WORD) + TOK_WORD_BIT;
// Contexts that affect the parsing of words
public static final int BASE_CONTEXT = 0;
public static final int RULE_1_CONTEXT = 1;
public static final int RULE_5_CONTEXT = 5;
public static final int RULE_6_CONTEXT = 6;
public static final int RULE_7a_CONTEXT = 7;
public static final int RULE_7b_CONTEXT = 8;
public static final int RULE_8_CONTEXT = 9;
/*
* We don't need / use use rules 2, 3 or 9 in a call to next(..) or peek(..)
* because the tokenizer doesn't perform expansion or assignment.
*/
public BjorneToken(final int tokenType, final String text, int start, int end) {
super(text == null ? "" : text, tokenType, start, end);
validate();
}
public BjorneToken(final String text) {
super(text == null ? "" : text, TOK_WORD, 0, 0);
validate();
}
public BjorneToken remake(CharSequence newText) {
if (newText.length() == 0) {
return null;
} else {
return new BjorneToken(this.tokenType, newText.toString(), this.start, this.end);
}
}
private void validate() {
// switch (tokenType) {
// case TOK_WORD:
// case TOK_IO_NUMBER:
// case TOK_NAME:
// case TOK_ASSIGNMENT:
// if (text == null || text.length() == 0) {
// throw new IllegalArgumentException("null or empty text");
// }
// break;
//
// default:
// if (text != null && text.length() > 0) {
// throw new IllegalArgumentException("non-empty text");
// }
// }
}
public String getText() {
return text;
}
public int getTokenType() {
return tokenType;
}
public boolean isName() {
return text != null && isName(text);
}
public static boolean isName(String str) {
int len = str.length();
if (len == 0) {
return false;
}
for (int i = 0; i < len; i++) {
char ch = str.charAt(i);
switch (ch) {
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
case 'G':
case 'H':
case 'I':
case 'J':
case 'K':
case 'L':
case 'M':
case 'N':
case 'O':
case 'P':
case 'Q':
case 'R':
case 'S':
case 'T':
case 'U':
case 'V':
case 'W':
case 'X':
case 'Y':
case 'Z':
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
case 'g':
case 'h':
case 'i':
case 'j':
case 'k':
case 'l':
case 'm':
case 'n':
case 'o':
case 'p':
case 'q':
case 'r':
case 's':
case 't':
case 'u':
case 'v':
case 'w':
case 'x':
case 'y':
case 'z':
case '_':
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
if (i == 0) {
return false;
}
break;
default:
return false;
}
}
return true;
}
public String toString() {
switch (tokenType) {
case TOK_WORD:
return "WORD{" + text + "}";
case TOK_NAME:
return "NAME{" + text + "}";
case TOK_ASSIGNMENT:
return "ASSIGNMENT{" + text + "}";
case TOK_IO_NUMBER:
return "IO_NUMBER{" + text + "}";
default:
String str = toString(tokenType);
return str == null ? "?UNKNOWN?" : str;
}
}
public static String toString(int tt) {
switch (tt) {
case TOK_SEMI:
return ";";
case TOK_AMP:
return "&";
case TOK_BAR:
return "|";
case TOK_LESS:
return "<";
case TOK_GREAT:
return ">";
case TOK_LPAREN:
return "(";
case TOK_RPAREN:
return ")";
case TOK_LBRACE:
return "{";
case TOK_RBRACE:
return "}";
case TOK_BANG:
return "!";
case TOK_AND_IF:
return "&&";
case TOK_OR_IF:
return "||";
case TOK_DSEMI:
return ";;";
case TOK_DLESS:
return "<<";
case TOK_DGREAT:
return ">>";
case TOK_LESSAND:
return "<&";
case TOK_GREATAND:
return ">&";
case TOK_LESSGREAT:
return "<>";
case TOK_DLESSDASH:
return "<<-";
case TOK_CLOBBER:
return "|>";
case TOK_IF:
return "if";
case TOK_THEN:
return "then";
case TOK_ELSE:
return "else";
case TOK_ELIF:
return "elif";
case TOK_FI:
return "fi";
case TOK_DO:
return "do";
case TOK_DONE:
return "done";
case TOK_CASE:
return "case";
case TOK_ESAC:
return "esac";
case TOK_WHILE:
return "while";
case TOK_UNTIL:
return "until";
case TOK_FOR:
return "for";
case TOK_IN:
return "in";
case TOK_END_OF_LINE:
return "end of line";
case TOK_END_OF_STREAM:
return "end of file";
case TOK_WORD:
return "<word>";
case TOK_NAME:
return "<name>";
case TOK_ASSIGNMENT:
return "<assignment>";
case TOK_IO_NUMBER:
return "<io number>";
case TOK_COMMAND_NAME:
return "<command name>";
case TOK_COMMAND_WORD:
return "<command word>";
case TOK_FUNCTION_NAME:
return "<function name>";
case TOK_HERE_END:
return "<here end>";
case TOK_FOR_NAME:
return "<for name>";
case TOK_FOR_WORD:
return "<for word>";
case TOK_PATTERN:
return "<case pattern>";
case TOK_FILE_NAME:
return "<file name>";
case TOK_CASE_WORD:
return "<case word>";
default:
return "unknown (" + tt + ")";
}
}
public String unparse() {
if (text != null && text.length() > 0) {
return text;
} else if (tokenType != TOK_END_OF_LINE && tokenType != TOK_END_OF_STREAM) {
return toString(tokenType);
} else {
return "";
}
}
public static String formatExpectedSet(long expectedSet) {
StringBuilder sb = new StringBuilder(40);
long mask = 1L;
for (int i = 0; i < 64 && expectedSet != 0L; i++) {
if ((expectedSet & mask) != 0) {
if (sb.length() > 0) {
if (expectedSet != 0L) {
sb.append(", ");
} else {
sb.append(" or ");
}
}
sb.append(BjorneToken.toString(i));
expectedSet &= ~mask;
}
mask <<= 1;
}
return sb.toString();
}
public static String toString(BjorneToken token) {
return token != null ? (token + "/" + token.start + "/" + token.end) : "null";
}
}