📄 patterncompiler.jjt
字号:
/* * FindBugs - Find bugs in Java programs * Copyright (C) 2004 University of Maryland * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *//* * This file should be processed with JavaCC (https://javacc.dev.java.net/): * first with the "jjtree" command, then with the "javacc" command. */options { STATIC = false; LOOKAHEAD = 2; FORCE_LA_CHECK = true; NODE_SCOPE_HOOK = true;}PARSER_BEGIN(PatternCompiler)package edu.umd.cs.findbugs.tools.patcomp;/** * A compiler to translate FindBugs Pattern (.fbp) files * into Java source files. This provides a high level mechanism * for implementing new bug pattern detectors. * * @author David Hovemeyer */public class PatternCompiler { public static void main(String[] argv) throws Exception { PatternCompiler pc = new PatternCompiler(System.in); SimpleNode root = pc.unit(); new CodeGen().generate(root, new PrettyCodeEmitter(System.out)); } void jjtreeOpenNodeScope(Node node) { ((SimpleNode)node).setFirstToken(getToken(1)); } void jjtreeCloseNodeScope(Node node) { ((SimpleNode)node).setLastToken(getToken(0)); }}PARSER_END(PatternCompiler)SKIP :{ " "| "\t"| "\n"| "\r"}MORE :{ "//" : IN_SINGLE_LINE_COMMENT}<IN_SINGLE_LINE_COMMENT>SPECIAL_TOKEN :{ <SINGLE_LINE_COMMENT: "\n"|"\r"|"\r\n"> : DEFAULT}<IN_SINGLE_LINE_COMMENT>MORE :{ < ~[] >}TOKEN :{ // Our keywords <PRESCREEN: "prescreen">| <MATCH: "match">| <CHECK: "check">| <REPORT: "report">| <WHERE: "where">| <DOMINATEDBY: "dominatedby">| <BLOCKS: "blocks">| <VARS: "vars"> // Java keywords - needed to understand Java expressions| <VOID: "void">| <BOOLEAN: "boolean">| <BYTE: "byte">| <CHAR: "char">| <SHORT: "short">| <INT: "int">| <FLOAT: "float">| <LONG: "long">| <DOUBLE: "double">| <THIS: "this">| <SUPER: "super">| <CLASS: "class">| <INSTANCEOF: "instanceof">| <TRUE: "true">| <FALSE: "false">| <NULL: "null">| <NEW: "new"> // Identifiers| <ID: <IDSTART>(<IDCHAR>)*> // Syntax bits| <LBRACE: "{">| <RBRACE: "}">| <LPAREN: "(">| <RPAREN: ")">| <LBRACKET: "[">| <RBRACKET: "]">| <DOT: ".">| <COMMA: ",">| <SEMICOLON: ";">| <COLON: ":">| <QUES: "?">| <OR: "||">| <AND: "&&">| <BITOR: "|">| <BITXOR: "^">| <BITAND: "&">| <EQ: "==">| <NEQ: "!=">| <LE: "<=">| <GE: ">=">| <LSHIFT: "<<">| <BRSHIFT: ">>>">| <RSHIFT: ">>">| <LT: "<">| <GT: ">">| <INC: "++">| <DEC: "--">| <PLUS: "+">| <MINUS: "-">| <TIMES: "*">| <DIV: "/">| <MOD: "%">| <COMPL: "~">| <NOT: "!">| <ASSIGN: "="> // Literals| <INT_LITERAL: <DEC_LITERAL>|<HEX_LITERAL>>| <FP_LITERAL: (<DIGIT>)+ "." (<DIGIT>)* (<EXP>)? (<FP_SUFFIX>)? | "." (<DIGIT>)+ (<EXP>)? (<FP_SUFFIX>)? | (<DIGIT>)+ <EXP> (<FP_SUFFIX>)? | (<DIGIT>)+ (<EXP>)? (<FP_SUFFIX>)>| <CHAR_LITERAL: "'" (<NOT_SPECIAL_IN_CHAR_LITERAL>|<STRING_ESCAPE>) "'">| <STRING_LITERAL: "\"" (<NOT_SPECIAL_IN_STRING_LITERAL>|<STRING_ESCAPE>)* "\"">| <#DEC_LITERAL: (<DIGIT>)+(["L","l"])?>| <#HEX_LITERAL: "0" ("X"|"x") (["A"-"F","a"-"f"])+>| <#EXP: (["E","e"]) (["+","-"])? (<DIGIT>)+>| <#STRING_ESCAPE: "\\" (<ORDINARY_STRING_ESCAPE>|<OCTAL_ESCAPE>)>| <#OCTAL_ESCAPE: (<OCTAL_DIGIT> (<OCTAL_DIGIT>)?) | (<ZERO_TO_THREE> <OCTAL_DIGIT> <OCTAL_DIGIT>)> // Character classes| <#IDSTART: (["A"-"Z"]|["a"-"z"]|"_")>| <#IDCHAR: (["A"-"Z"]|["a"-"z"]|<DIGIT>|"_")>| <#DIGIT: ["0"-"9"]>| <#OCTAL_DIGIT: ["0"-"7"]>| <#ZERO_TO_THREE: ["0"-"3"]>| <#FP_SUFFIX: (["F","f","D","d"])>| <#NOT_SPECIAL_IN_CHAR_LITERAL: ~["'","\\","\n","\r"]>| <#NOT_SPECIAL_IN_STRING_LITERAL: ~["\"","\\","\n","\r"]> | <#ORDINARY_STRING_ESCAPE: (["t","r","n","f","b","\\","'","\""])>}// Top level production.SimpleNode unit() :{ }{ [ prescreen() ] match() [ check() ] report() { return jjtThis; }}// The optional "prescreen" section specifies simple/fast checks// done on the method to determine whether or not the method// might contain an instance of the pattern.void prescreen() :{ }{ <PRESCREEN> <LBRACE> [ declaration_section() ] expression() <RBRACE>}// The required "match" section specifies a bytecode pattern// to search for.void match() :{ }{ <MATCH> <LBRACE> ( instruction() )+ <RBRACE>}// The optional "check" section performs tests on the code matched// by the pattern in the "match" section to determine whether// it is really an instance of the pattern. These checks may make// use of more extensive analysis such as computing lock sets.void check() :{ }{ <CHECK> <LBRACE> [ declaration_section() ] expression() <RBRACE>}// The required "report" section emits a bug warning based on the// matched code.void report() :{ }{ <REPORT> <LBRACE> [ declaration_section() ] expression() <RBRACE>}void declaration_section() :{ }{ <VARS> <LBRACE> ( declaration() )+ <RBRACE>}void declaration() :{ }{ type_spec() <ID> <ASSIGN> expression() <SEMICOLON>}void instruction() :{ }{ [ label() ] <ID> [ instruction_arg_list() ] [ <DOMINATEDBY> <LPAREN> <ID> <RPAREN> ] [ <WHERE> <LPAREN> expression() <RPAREN> ] <SEMICOLON>}void label() :{ }{ <ID> <COLON>}void instruction_arg_list() :{ }{ <ID> [ instruction_arg_list_rest() ]}void instruction_arg_list_rest() :{ }{ <COMMA> <ID> [ instruction_arg_list_rest() ]}/* * Expression grammar. * This was adapted from the ANTLR grammar for Java 1.5 * at http://www.thecortex.net/clover/generics/javaG.g, * which is in the public domain. * * Augmented expressions: * - "blocks b where (exp)": select a subset of blocks from CFG * by evaluating expression for each basic block "b". * Result is a Region. * * Limitations: * - Assignment operators are not allowed. * - Generics are not allowed. * - Casts are not allowed. * - "new" expressions are not allowed. */void expression() :{ }{ logical_or_expression() [ <QUES> expression() <COLON> expression() ]}void logical_or_expression() :{ }{ logical_and_expression() ( <OR> logical_and_expression() )*}void logical_and_expression() :{ }{ inclusive_or_expression() ( <AND> inclusive_or_expression() )*}void inclusive_or_expression() :{ }{ exclusive_or_expression() ( <BITOR> exclusive_or_expression() )*}void exclusive_or_expression() :{ }{ and_expression() ( <BITXOR> and_expression() )*}void and_expression() :{ }{ equality_expression() ( <BITAND> equality_expression() )*}void equality_expression() :{ }{ relational_expression() ( (<NEQ>|<EQ>) relational_expression() )*}void relational_expression() :{ }{ shift_expression() ( <INSTANCEOF> type_spec() | ( (<LT> | <GT> | <LE> | <GE>) shift_expression() )* )}/*void relational_expression_rest() :{ }{ <INSTANCEOF> type_spec()| ( (<LT> | <GT> | <LE> | <GE>) shift_expression() )*}*/void shift_expression() :{ }{ additive_expression() ( (<LSHIFT> | <RSHIFT> | <BRSHIFT>) additive_expression() )*}void additive_expression() :{ }{ multiplicative_expression() ( (<PLUS> | <MINUS>) multiplicative_expression() )*}void multiplicative_expression() :{ }{ unary_expression() ( (<TIMES>|<DIV>|<MOD>) unary_expression() )*}void unary_expression() :{ }{ <INC> unary_expression()| <DEC> unary_expression()| <MINUS> unary_expression()| <PLUS> unary_expression()| <COMPL> unary_expression()| <NOT> unary_expression()| postfix_expression()}void postfix_expression() :{ }{ primary_expression() ( postfix_expression_rest() )* ( (<INC>|<DEC>) )*}void postfix_expression_rest() :{ }{ <DOT> <ID> [ <LPAREN> [ arg_list() ] <RPAREN> ]| <DOT> <THIS>| <DOT> <SUPER> [ postfix_super_rest() ]| <LBRACKET> expression() <RBRACKET>}void postfix_super_rest() :{ }{ <LPAREN> [ arg_list() ] <RPAREN>| <DOT> <ID> [ <LPAREN> [ arg_list() ] <RPAREN> ]}void primary_expression() :{ }{ ident_primary() [ <DOT> <CLASS> ]| constant()| <TRUE>| <FALSE>| <NULL>| <THIS>| <SUPER>| <LPAREN> expression() <RPAREN>| builtin_type() [ array_spec() ] <DOT> <CLASS>| <BLOCKS> <ID> <WHERE> <LPAREN> expression() <RPAREN>}void ident_primary() :{ }{ <ID> ( <DOT> <ID> )* [ <LPAREN> [ arg_list() ] <RPAREN> ] }void constant() :{ }{ <INT_LITERAL> | <FP_LITERAL> | <CHAR_LITERAL> | <STRING_LITERAL>}void type_spec() :{ }{ class_type_spec()| builtin_type_spec()}void class_type_spec() :{ }{ class_or_interface_type_name() [ array_spec() ]}void class_or_interface_type_name() :{ }{ <ID> ( <DOT> <ID> )*}void builtin_type_spec() :{ }{ builtin_type() [ array_spec() ]}void builtin_type() :{ }{ <VOID> | <BOOLEAN> | <BYTE> | <CHAR> | <SHORT> | <INT> | <FLOAT> | <LONG> | <DOUBLE>}void array_spec() :{ }{ ( <LBRACKET> <RBRACKET> )+}void arg_list() :{ }{ expression() [ arg_list_rest() ]}void arg_list_rest() :{ }{ <COMMA> expression() [ arg_list_rest() ]}// vim:ts=4
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -