📄 lexparse.cup
字号:
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * JFlex 1.4.2 * * Copyright (C) 1998-2008 Gerwin Klein <lsf@jflex.de> * * All rights reserved. * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License. See the file * * COPYRIGHT for more information. * * * * This program 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 General Public License for more details. * * * * You should have received a copy of the GNU General Public License along * * with this program; if not, write to the Free Software Foundation, Inc., * * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */package JFlex;import java.util.*;/* customizing code */action code {: LexScan scanner; CharClasses charClasses = new CharClasses(Options.jlex ? 127 : 0xFFFF); RegExps regExps = new RegExps(); Macros macros = new Macros(); Integer stateNumber; Timer t = new Timer(); EOFActions eofActions = new EOFActions(); void fatalError(ErrorMessages message, int line, int col) { syntaxError(message, line, col); throw new GeneratorException(); } void fatalError(ErrorMessages message) { fatalError(message, scanner.currentLine(), -1); throw new GeneratorException(); } void syntaxError(ErrorMessages message) { Out.error(scanner.file, message, scanner.currentLine(), -1); } void syntaxError(ErrorMessages message, int line) { Out.error(scanner.file, message, line, -1); } void syntaxError(ErrorMessages message, int line, int col) { Out.error(scanner.file, message, line, col); } private boolean check(int type, char c) { switch (type) { case sym.JLETTERCLASS: return Character.isJavaIdentifierStart(c); case sym.JLETTERDIGITCLASS: return Character.isJavaIdentifierPart(c); case sym.LETTERCLASS: return Character.isLetter(c); case sym.DIGITCLASS: return Character.isDigit(c); case sym.UPPERCLASS: return Character.isUpperCase(c); case sym.LOWERCLASS: return Character.isLowerCase(c); default: return false; } } private Vector makePreClass(int type) { Vector result = new Vector(); char c = 0; char start = 0; char last = charClasses.getMaxCharCode(); boolean prev, current; prev = check(type,'\u0000'); for (c = 1; c < last; c++) { current = check(type,c); if (!prev && current) start = c; if (prev && !current) { result.addElement(new Interval(start, (char)(c-1))); } prev = current; } // the last iteration is moved out of the loop to // avoid an endless loop if last == maxCharCode and // last+1 == 0 current = check(type,c); if (!prev && current) result.addElement(new Interval(c,c)); if (prev && current) result.addElement(new Interval(start, c)); if (prev && !current) result.addElement(new Interval(start, (char)(c-1))); return result; } private RegExp makeRepeat(RegExp r, int n1, int n2, int line, int col) { if (n1 <= 0 && n2 <= 0) { syntaxError(ErrorMessages.REPEAT_ZERO, line, col); return null; } if (n1 > n2) { syntaxError(ErrorMessages.REPEAT_GREATER, line, col); return null; } int i; RegExp result; if (n1 > 0) { result = r; n1--; n2--; // we need one concatenation less than the number of expressions to match } else { result = new RegExp1(sym.QUESTION,r); n2--; } for (i = 0; i < n1; i++) result = new RegExp2(sym.CONCAT, result, r); n2-= n1; for (i = 0; i < n2; i++) result = new RegExp2(sym.CONCAT, result, new RegExp1(sym.QUESTION,r)); return result; } private RegExp makeNL() { Vector list = new Vector(); list.addElement(new Interval('\n','\r')); list.addElement(new Interval('\u0085','\u0085')); list.addElement(new Interval('\u2028','\u2029')); // assumption: line feeds are caseless charClasses.makeClass(list, false); charClasses.makeClass('\n', false); charClasses.makeClass('\r', false); RegExp1 c = new RegExp1(sym.CCLASS, list); Character n = new Character('\n'); Character r = new Character('\r'); return new RegExp2(sym.BAR, c, new RegExp2(sym.CONCAT, new RegExp1(sym.CHAR, r), new RegExp1(sym.CHAR, n))); } :};parser code {: public LexScan scanner; public LexParse(LexScan scanner) { super(scanner); this.scanner = scanner; } public CharClasses getCharClasses() { return action_obj.charClasses; } public EOFActions getEOFActions() { return action_obj.eofActions; } public void report_error(String message, Object info) { if ( info instanceof java_cup.runtime.Symbol ) { java_cup.runtime.Symbol s = (java_cup.runtime.Symbol) info; if (s.sym == sym.EOF) Out.error(ErrorMessages.UNEXPECTED_EOF); else Out.error(scanner.file, ErrorMessages.SYNTAX_ERROR, s.left, s.right); } else Out.error(ErrorMessages.UNKNOWN_SYNTAX); } public void report_fatal_error(String message, Object info) { // report_error(message, info); throw new GeneratorException(); }:};init with {: action_obj.scanner = this.scanner;:};/* token declarations */terminal OPENBRACKET, CLOSEBRACKET, HAT, DOLLAR, OPENCLASS, CLOSECLASS, DASH, DELIMITER, EQUALS, COMMA, LESSTHAN, MORETHAN, LBRACE, RBRACE, ASCII, FULL, UNICODE, REGEXPEND;terminal JLETTERCLASS, JLETTERDIGITCLASS, LETTERCLASS, DIGITCLASS, UPPERCLASS, LOWERCLASS, EOFRULE, NOACTION, LOOKAHEAD; terminal Action ACTION;terminal String IDENT, USERCODE;terminal Integer REPEAT;/* tokens used in RegExp parse tree */terminal STAR, PLUS, BAR, QUESTION, POINT, BANG, TILDE;terminal Character CHAR;terminal String STRING, MACROUSE;/* symbols *only* used in the parse tree (not in the grammar) */terminal CCLASS, CCLASSNOT, CONCAT;terminal STRING_I, CHAR_I; /* case insensitive strings/chars */non terminal macros, macro;non terminal Integer rule;non terminal NFA specification;non terminal RegExp series, concs, nregexp, regexp, charclass, lookahead;non terminal Interval classcontentelem;non terminal Vector states, statesOPT, classcontent, preclass, rules;non terminal Boolean hatOPT;non terminal Action act, actions;/* grammar specification */start with specification;specification ::= USERCODE /* delimiter is checked in lexer */ macros DELIMITER rules {: scanner.t.stop(); Out.checkErrors(); Out.time(ErrorMessages.PARSING_TOOK, t); macros.expand(); Enumeration unused = macros.unused(); while ( unused.hasMoreElements() ) { Out.warning("Macro \""+unused.nextElement()+"\" has been declared but never used."); } SemCheck.check(regExps, macros, scanner.file); regExps.checkActions(); regExps.checkLookAheads(); Out.checkErrors(); if (Options.dump) charClasses.dump(); Out.print("Constructing NFA : "); t.start(); int num = regExps.getNum(); RESULT = new NFA(charClasses.getNumClasses(), scanner, regExps, macros, charClasses); eofActions.setNumLexStates(scanner.states.number()); for (int i = 0; i < num; i++) { if (regExps.isEOF(i)) eofActions.add( regExps.getStates(i), regExps.getAction(i) ); else RESULT.addRegExp(i); } if (scanner.standalone) RESULT.addStandaloneRule(); t.stop(); Out.time(""); Out.time(ErrorMessages.NFA_TOOK, t); :} | /* emtpy spec. error */ {: fatalError(ErrorMessages.NO_LEX_SPEC); :} ; macros ::= /* empty, most switches & state declarations are parsed in lexer */ | macros macro | error;macro ::= ASCII {: charClasses.setMaxCharCode(127); :} | FULL {: charClasses.setMaxCharCode(255); :} | UNICODE {: charClasses.setMaxCharCode(0xFFFF); :} | IDENT:name EQUALS series:definition REGEXPEND {: macros.insert(name, definition); :} | IDENT EQUALS:e {: syntaxError(ErrorMessages.REGEXP_EXPECTED, eleft, eright); :}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -