Imported Upstream version 2.9.1+ds
[debian/jabref.git] / src / java / net / sf / jabref / search / Parser.g
1 header {\r
2 package net.sf.jabref.search;\r
3 import java.io.StringReader;\r
4 }\r
5 \r
6 class SearchExpressionParser extends Parser;\r
7 \r
8 options {\r
9         importVocab = SearchExpressionLexer; // use vocab generated by lexer\r
10         exportVocab = SearchExpressionParser;\r
11         defaultErrorHandler = false;\r
12         buildAST = true;\r
13         k = 3;\r
14 }\r
15 \r
16 tokens {\r
17         RegularExpression;\r
18         And;\r
19         Or;\r
20         Not;\r
21         ExpressionSearch;\r
22 }\r
23 \r
24 // ---------- Java Source Code ----------\r
25 \r
26 {\r
27         public boolean caseSensitive = false;\r
28     public boolean regex = true;\r
29         /** Creates a parser and lexer instance and tests the specified String.\r
30           * Returns the AST if s is in valid syntax for advanced field search, null otherwise. */\r
31         public static AST checkSyntax(String s, boolean caseSensitive, boolean regex) {\r
32                 // Is there some way to prevent instance creation here?\r
33                 // How can a parser and/or lexer be reused?\r
34                 SearchExpressionParser parser = new SearchExpressionParser(new SearchExpressionLexer(\r
35                                 new StringReader(s)));\r
36                 parser.caseSensitive = caseSensitive;\r
37                 parser.regex = regex;\r
38                 try {\r
39                         parser.searchExpression();\r
40                         return parser.getAST();\r
41                 } catch (Exception e) {\r
42                         return null;\r
43                 }\r
44         }\r
45 }\r
46 \r
47 // ---------- Text and Regular Expressions ----------\r
48 \r
49 quotedRegularExpression[boolean caseSensitive, boolean regex]:\r
50                 var_s:STRING\r
51                         {\r
52                                 ## = astFactory.make((new ASTArray(2)).add(new RegExNode(RegularExpression,var_s.getText(),caseSensitive,regex)).add(##));\r
53                         }\r
54                 ;\r
55 \r
56 simpleRegularExpression[boolean caseSensitive, boolean regex]:\r
57                 var_s:FIELDTYPE\r
58                         {\r
59                                 ## = astFactory.make((new ASTArray(2)).add(new RegExNode(RegularExpression,var_s.getText(),caseSensitive,regex)).add(##));\r
60                         }\r
61                 ;\r
62 \r
63 // ---------- Condition and Expressions ----------\r
64 \r
65 searchExpression:\r
66         condition EOF;\r
67 \r
68 condition:\r
69                 (expression LITERAL_and condition) => expression LITERAL_and! condition { ## = #( [And], ##); }\r
70                 |\r
71                 (expression LITERAL_or condition) => expression LITERAL_or! condition { ## = #( [Or], ##); }\r
72                 |\r
73                 expression // negation is done in expression\r
74                 ;\r
75 \r
76 expression:\r
77                 expressionSearch\r
78                 |\r
79                 LPAREN! condition RPAREN!\r
80                 |\r
81                 LITERAL_not! expressionSearch { ## = #( [Not], ## ); }         // NOT single expression\r
82                 |\r
83                 LITERAL_not! LPAREN! condition RPAREN! { ## = #( [Not], ## ); } // NOT ( ... )\r
84                 ;\r
85 \r
86 expressionSearch:\r
87                 quotedRegularExpression[false,true] compareType quotedRegularExpression[caseSensitive,regex]\r
88                         { ## = #( [ExpressionSearch], ## ); }\r
89                 |\r
90                 simpleRegularExpression[false,true] compareType quotedRegularExpression[caseSensitive,regex]\r
91                         { ## = #( [ExpressionSearch], ## ); }\r
92                 |\r
93                 simpleRegularExpression[false,true] compareType simpleRegularExpression[caseSensitive,regex]\r
94                         { ## = #( [ExpressionSearch], ## ); }\r
95                 |\r
96                 quotedRegularExpression[false,true] compareType simpleRegularExpression[caseSensitive,regex]\r
97                         { ## = #( [ExpressionSearch], ## ); }\r
98                 ;\r
99 \r
100 compareType:\r
101                 LITERAL_contains | LITERAL_matches | EQUAL | EEQUAL | NEQUAL\r
102                 ;\r
103 \r