- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
首先,我承认:这可能是您一生中见过的最丑陋的语法之一(具有讽刺意味的是,它被命名为 SimplePolicy.g)。它开始是一个简单的语法,但我最终需要更详细的异常,所以我最终创建了多个扩展 RecognitionException 的异常。然后是一个 RuntimeException 来包装它,这样我就可以退出解析器方法。
此语法应该验证一组一个或多个 IF/THEN/ELSE?/ENDIF 语句。不幸的是,当我尝试将 INTEGER_FIELD token 之一与 INTEGER token 进行比较时,INTEGER token 已从 TokenInputStream 中完全消失。我试过通过 println() 来弄清楚发生了什么,但没有成功。
这是一个失败的例子:
如果年龄 < 21 那么重量 > 150结束
似乎正在发生的事情是输入字符串是好的,但是当我通过 CharStream 将它提供给 Lexer 时,正在比较 AGE 和 WT 的整数常量消失了。
这是一个单元测试:
@Test
public void ifStatement_legalPolicy2_passes() {
String policy = "IF AGE < 21 THEN "+
"WT > 150 "+
"ENDIF";
CharStream charStream = new ANTLRStringStream(policy);
SimplePolicyLexer lexer = new SimplePolicyLexer(charStream);
TokenStream tokenStream = new CommonTokenStream(lexer);
System.out.println(tokenStream.toString());
SimplePolicyParser parser = new SimplePolicyParser(tokenStream);
try {
parser.ifStatement();
parser.reset();
} catch (RecognitionRuntimeException e) {
RecognitionException e1 = e.getRecognitionException();
fail("Legal policy should not have thrown exception. Exception thrown: " + e1.getClass().getName() + ". Line: " + e1.line + ", Column: " + e1.charPositionInLine);
} catch (RecognitionException e) {
}
}
这是 token 流的字符串输出:
13:14:14.978 DEBUG m.a.k.m.impl.SimplePolicyParser - ifStatement: IF AGE < THEN WT > ENDIF
对于这种语法的丑陋,我深表歉意,但如果有人能告诉我为什么它会消失,我将不胜感激。
grammar SimplePolicy;
options {
language = Java;
backtrack = true;
}
@header {
package com.manager.impl;
import com.manager.RecognitionRuntimeException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Arrays;
@lexer::header {
package com.manager.impl;
}
@lexer::members {
}
@parser::members {
private static final Logger log = LoggerFactory.getLogger(SimplePolicyParser.class);
@Override
protected Object recoverFromMismatchedToken(IntStream input, int ttype, BitSet follow) throws RecognitionException {
throw new MismatchedTokenException(ttype, input);
}
@Override
public Object recoverFromMismatchedSet(IntStream input, RecognitionException e, BitSet follow) throws RecognitionException {
throw e;
}
@Override
public String getErrorMessage(RecognitionException e, String[] tokenNames) {
// wrap in a runtime exception to escape ANTLR's dungeon
throw new RecognitionRuntimeException(e);
}
}
@rulecatch {
catch (RecognitionException e) {
System.out.println(getErrorHeader(e));
//System.out.println(getErrorMessage(e,tokenNames));
throw new RecognitionRuntimeException(e);
}
}
// evaluate multiple show statements
policyGroupWithShow
: show (show)* EOF
| ifStatement+ EOF
{
// nope, this isn't legal
ShowExpectedException ex = new ShowExpectedException();
ex.line = 1;
ex.charPositionInLine=0;
throw ex;
}
;
policyGroupWithoutShow
: ifStatement (ifStatement)* EOF
| show+ EOF
{
// not legal
UnexpectedSymbolOrConstructionException ex = new UnexpectedSymbolOrConstructionException();
ex.line = 1;
ex.charPositionInLine = 0;
throw ex;
}
;
//policyGroup
// : show (show)* EOF
// ;
// evaluate a single SHOW statement
show
//: ifStatement
: SHOW STRING FOR ifStatement // good
// missing for (FOR expected)
| SHOW expr1a=STRING ifStatement // missing for
{
int nextTokenPosition = expr1a.getTokenIndex();
CommonToken token = (CommonToken) input.get(nextTokenPosition + 1);
ShowWithoutForException ex = new ShowWithoutForException();
ex.line = expr1a.getLine();
ex.charPositionInLine = token.getCharPositionInLine();
throw ex;
}
// missing show (SHOW expected)
| expr1b=STRING FOR ifStatement
{
int tokenPosition = expr1b.getTokenIndex();
CommonToken token = (CommonToken) input.get(tokenPosition);
ForWithoutShowException ex = new ForWithoutShowException();
ex.line = token.getLine();
ex.charPositionInLine = token.getStartIndex();
throw ex;
}
;
ifStatement
@init {
log.debug("ifStatement: " + input.toString());
}
//: IF logical THEN logical+ (ELSE logical+)? ENDIF
: IF operation 'THEN' expression+ ENDIF // good
{
log.debug("Matched [IF logical THEN expression+ ENDIF]");
}
| IF logical THEN expression+ ELSE expression+ ENDIF
{
log.debug("Matched [IF logical THEN expression+ ELSE expression+ ENDIF]");
}
| logical expr1a=THEN expression* (ELSE expression*)? ENDIF // missing if
{
int tokenPosition = expr1a.getTokenIndex();
CommonToken token = (CommonToken) input.get(tokenPosition);
MissingIfException ex = new MissingIfException();
ex.line = token.getLine();
ex.charPositionInLine = 0;
throw ex;
}
// missing THEN (THEN clause is missing)
| expr1b=IF logical expression+ (ELSE expression+)? ENDIF
{
int tokenPosition = expr1b.getTokenIndex();
CommonToken token = (CommonToken) input.get(tokenPosition + 1);
MissingThenClauseException ex = new MissingThenClauseException();
ex.line = token.getLine();
ex.charPositionInLine = token.getCharPositionInLine();
throw ex;
}
// missing ELSE or ENDIF (ENDIF Expected)
| IF logical expr1c=THEN expression+
{
String inputText = input.toString();
if (inputText.indexOf("ELSE") < 0 && inputText.indexOf("ENDIF") < 0) {
// best I can do is get the line/column from the THEN keyword
MissingElseOrEndifException ex = new MissingElseOrEndifException();
ex.line = expr1c.getLine();
ex.charPositionInLine = expr1c.getCharPositionInLine();
throw ex;
}
}
// missing comparison for IF (rule expected)
| IF expr1d=THEN expression* ENDIF
{
int tokenPosition = expr1d.getTokenIndex();
CommonToken token = (CommonToken) input.get(tokenPosition - 1);
RuleExpectedException ex = new RuleExpectedException();
ex.line = token.getLine();
ex.charPositionInLine = token.getStopIndex();
throw ex;
}
// missing body of then (unexpected symbol or construction)
| IF logical a=THEN b=ENDIF
{
int tokenPosition1 = a.getTokenIndex();
int tokenPosition2 = b.getTokenIndex();
CommonToken tokenA = (CommonToken) input.get(tokenPosition1);
CommonToken tokenB = (CommonToken) input.get(tokenPosition2);
UnexpectedSymbolOrConstructionException ex = new UnexpectedSymbolOrConstructionException();
//MissingThenBodyException ex = new MissingThenBodyException();
if (tokenA.getLine() == tokenB.getLine()) {
ex.line = tokenA.getLine();
ex.charPositionInLine = tokenA.getCharPositionInLine();
} else {
ex.line = tokenA.getLine() + 1;
ex.charPositionInLine = 0;
}
throw ex;
}
// missing body of ELSE (Unexpected symbol or construction)
| IF logical THEN expression+ ELSE expr3e=ENDIF
{
UnexpectedSymbolOrConstructionException ex = new UnexpectedSymbolOrConstructionException();
ex.line = expr3e.getLine();
ex.charPositionInLine = expr3e.getCharPositionInLine();
throw ex;
}
// body of IF missing (Body of IF clause is missing)
| IF expr3f=ENDIF
{
int tokenPosition = expr3f.getTokenIndex();
CommonToken token = (CommonToken) input.get(tokenPosition);
MissingIfBodyException ex = new MissingIfBodyException();
ex.line = token.getLine();
ex.charPositionInLine = token.getCharPositionInLine();
throw ex;
}
| expression // expression should just pass through
;
expression
@init {
log.debug("Expression: " + input.toString());
}
: logical
;
// deal with AND/OR operator
logical
@init {
log.debug("Logical:" + input.toString());
}
: operation (AND operation | OR operation)*
;
operation
@init {
log.debug("Operation:" + input.LT(1) + input.LT(2) + input.LT(3));
}
// good rules
//: ';' ~('/r/n'|EOF)*
: DATE_FIELD (EQ|NE|LT|LE|GT|GE) (DATE_FIELD|DATE|DATE_CONSTANT)
{
log.info("Matched STRING_FIELD (EQ|NE) (STRING_FIELD|STRING) field operation: " + input.toString());
}
| DATE_FIELD (PLUS|MINUS) (DATE_FIELD|DATE|DATE_CONSTANT|DATE_PERIOD_FIELD|datePeriod)
{
log.info("Matched DATE_FIELD (PLUS|MINUS) (DATE_FIELD|DATE|DATE_CONSTANT|DATE_PERIOD_FIELD|datePeriod) field operation: " + input.toString());
}
| DATE_PERIOD_FIELD (EQ|NE|LT|LE|GT|GE) (DATE_PERIOD_FIELD|DATE_PERIOD_CONSTANT)
{
log.info("Matched DATE_PERIOD_FIELD (EQ|NE|LT|LE|GT|GE) (DATE_PERIOD_FIELD|DATE_PERIOD_CONSTANT) field operation: " + input.toString());
}
| DATE_PERIOD_FIELD (PLUS|MINUS) (DATE_PERIOD_FIELD|datePeriod|DATE_FIELD|DATE_CONSTANT|DATE)
{
log.info("Matched DATE_PERIOD_FIELD (PLUS|MINUS) (DATE_PERIOD_FIELD|datePeriod|DATE_FIELD|DATE_CONSTANT|DATE) field operation: " + input.toString());
}
| STRING_FIELD (EQ|NE) (STRING_FIELD|STRING)
{
log.info("Matched STRING_FIELD (EQ|NE) (STRING_FIELD|STRING) field operation: " + input.toString());
}
| INTEGER_FIELD (EQ|NE|LT|LE|GT|GE) test=inAllFields
{
Boolean result = $inAllFields.result;
Integer type = $inAllFields.tokenType;
//int testType = test.getType();
if (type != INTEGER && type != INTEGER_FIELD) {
IncompatibleTypeException ex = new IncompatibleTypeException();
//ex.line = test.getLine();
//ex.charPositionInLine = test.getStartIndex();
throw ex;
}
}
| INTEGER_FIELD (EQ|NE|LT|LE|GT|GE) test1=(INTEGER_FIELD|INTEGER)
{
log.info(test1.getText());
log.info("Matched INTEGER_FIELD (EQ|NE|LT|LE|GT|GE) (INTEGER_FIELD|INTEGER) field operation: " + input.toString());
}
| BOOLEAN_FIELD (EQ|NE) (BOOLEAN_FIELD|BOOLEAN_CONSTANT)
{
log.info("Matched BOOLEAN_FIELD (EQ|NE) (BOOLEAN_FIELD|BOOLEAN_CONSTANT) field operation: " + input.toString());
}
| COMMENT
{
log.info("Matched COMMENT field operation: " + input.toString());
}
// specify bad rules
// defined fields with no operation. The expression will be null if datePeriod isn't split off
| (INTEGER_FIELD|INTEGER) (PLUS|MINUS|EQ|NE|LT|LE|)
{
System.out.println("Will it work?");
}
| (datePeriod)|e1=(DATE_PERIOD_FIELD|DATE_FIELD|STRING_FIELD|INTEGER_FIELD|WAIVER_FIELD|BOOLEAN_FIELD|BOOLEAN_CONSTANT)
{
RelationalOperatorOrNotExpectedException ex = new RelationalOperatorOrNotExpectedException();
if (e1 == null) {
ex.line = 1;
ex.charPositionInLine = 0;
} else {
ex.line = e1.getLine();
ex.charPositionInLine = e1.getCharPositionInLine();
}
throw ex;
}
| e2=(INTEGER|DATE|DATE_CONSTANT)
{
RuleCannotBeginWithNumberOrDateException ex = new RuleCannotBeginWithNumberOrDateException();
ex.line = e2.getLine();
ex.charPositionInLine = e2.getCharPositionInLine();
throw ex;
}
// attempt to compare a date field to a different field type. Incompatable Type exception
| DATE_FIELD operator1a=(EQ|NE|LT|LE|GT|GE) (DATE_PERIOD_FIELD|datePeriod|STRING_FIELD|STRING|INTEGER_FIELD|INTEGER|WAIVER_FIELD|BOOLEAN_FIELD|BOOLEAN_CONSTANT)
{
int tokenPosition = operator1a.getTokenIndex();
CommonToken token = (CommonToken) input.get(tokenPosition + 2);
IncompatibleTypeException ex = new IncompatibleTypeException();
ex.line = token.getLine();
ex.charPositionInLine = token.getStartIndex();
throw ex;
}
// attempt to add/sub illegal field types to date (Relational Operator or NOT expected)
| DATE_FIELD operator1b=(PLUS|MINUS)
(STRING_FIELD|STRING|INTEGER_FIELD|WAIVER_FIELD|BOOLEAN_FIELD|BOOLEAN_CONSTANT)
{
int tokenPosition = operator1b.getTokenIndex();
CommonToken token = (CommonToken) input.get(tokenPosition+1);
RelationalOperatorOrNotExpectedException ex = new RelationalOperatorOrNotExpectedException();
ex.line = token.getLine();
ex.charPositionInLine = token.getStartIndex();
throw ex;
}
// attempting to add an int to a date field makes it assume it's a bad date period
| DATE_FIELD operator1c=(PLUS|MINUS) expr1c=(INTEGER)
{
int tokenPosition = operator1c.getTokenIndex();
CommonToken token = (CommonToken) input.get(tokenPosition + 1);
MissingYearsMonthsWeeksDaysException ex = new MissingYearsMonthsWeeksDaysException();
ex.line = token.getLine();
ex.charPositionInLine = token.getStartIndex();
throw ex;
}
// attempt to compare a String field to something besides a String field or String constant
| STRING_FIELD operator2a=(EQ|NE) ~(STRING_FIELD|STRING)
{
int tokenPosition = operator2a.getTokenIndex();
CommonToken token = (CommonToken) input.get(tokenPosition + 1);
IncompatibleTypeException ex = new IncompatibleTypeException();
ex.line = token.getLine();
ex.charPositionInLine = token.getStartIndex();
throw ex;
}
| expr2b=STRING_FIELD operator2b=(LT|LE|GT|GE) (STRING_FIELD|STRING)
{
int tokenPosition = operator2b.getTokenIndex();
CommonToken token = (CommonToken) input.get(tokenPosition + 1);
UnexpectedSymbolOrConstructionException ex = new UnexpectedSymbolOrConstructionException();
ex.line = token.getLine();
ex.charPositionInLine = token.getStartIndex();
throw ex;
}
| stringExpr3=STRING
{
RuleCannotBeginWithAStringException ex = new RuleCannotBeginWithAStringException();
ex.line = stringExpr3.getLine();
ex.charPositionInLine = stringExpr3.getCharPositionInLine();
throw ex;
}
// attempt to compare a number field to something besides a num field or int constant
| INTEGER_FIELD operator3a=(EQ|NE|LT|LE|GT|GE) expr3a2=(DATE_FIELD|DATE|STRING_FIELD|STRING|DATE_PERIOD_FIELD|WAIVER_FIELD|BOOLEAN_FIELD|BOOLEAN_CONSTANT)
{
Boolean value = $inAllFields.result;
//System.out.println("Expr text: " + expr3a2.getText());
int tokenPosition = operator3a.getTokenIndex();
CommonToken token = (CommonToken) input.get(tokenPosition + 1);
IncompatibleTypeException ex = new IncompatibleTypeException();
ex.line = token.getLine();
ex.charPositionInLine = token.getStartIndex();
throw ex;
}
// attempt to perform a PLUS/MINUS on a number field with something besides a num field or constant int
| INTEGER_FIELD operator3b=(PLUS|MINUS)
(DATE_FIELD|DATE|STRING_FIELD|STRING|DATE_PERIOD_FIELD|datePeriod|WAIVER_FIELD|BOOLEAN_FIELD|BOOLEAN_CONSTANT)
{
int tokenPosition = operator3b.getTokenIndex();
CommonToken token = (CommonToken) input.get(tokenPosition + 1);
IncompatibleTypeException ex = new IncompatibleTypeException();
ex.line = token.getLine();
ex.charPositionInLine = token.getStartIndex();
throw ex;
}
// attempt to compare date period to something besides a date period field or date period constant
| DATE_PERIOD_FIELD operator4a=(EQ|NE|LT|LE|GT|GE)
(INTEGER_FIELD|INTEGER|DATE_FIELD|DATE|DATE_CONSTANT|STRING_FIELD|STRING|BOOLEAN_FIELD|BOOLEAN_CONSTANT|WAIVER_FIELD)
{
int tokenPosition = operator4a.getTokenIndex();
CommonToken token = (CommonToken) input.get(tokenPosition + 1);
IncompatibleTypeException ex = new IncompatibleTypeException();
ex.line = token.getLine();
ex.charPositionInLine = token.getStartIndex();
throw ex;
}
| DATE_PERIOD_FIELD operator5a=(PLUS|MINUS) (STRING_FIELD|STRING|INTEGER_FIELD|WAIVER_FIELD|BOOLEAN_FIELD|BOOLEAN_CONSTANT)
{
int tokenPosition = operator5a.getTokenIndex();
CommonToken token = (CommonToken) input.get(tokenPosition + 1);
RelationalOperatorOrNotExpectedException ex = new RelationalOperatorOrNotExpectedException();
ex.line = token.getLine();
ex.charPositionInLine = token.getStartIndex();
throw ex;
}
| DATE_PERIOD_FIELD operator5b=(PLUS|MINUS) INTEGER
{
int tokenPosition = operator5b.getTokenIndex();
CommonToken token = (CommonToken) input.get(tokenPosition + 1);
MissingYearsMonthsWeeksDaysException ex = new MissingYearsMonthsWeeksDaysException();
ex.line = token.getLine();
ex.charPositionInLine = token.getStartIndex();
throw ex;
}
| WAIVER_FIELD operator6a=(HAS|EQ|NE) ~(STRING)
{
int tokenPosition = operator6a.getTokenIndex();
CommonToken token = (CommonToken) input.get(tokenPosition + 1);
IncompatibleTypeException ex = new IncompatibleTypeException();
ex.line = token.getLine();
ex.charPositionInLine = token.getStartIndex();
throw ex;
}
| WAIVER_FIELD operator6b=(PLUS|MINUS|LT|LE|GT|GE) STRING
{
int tokenPosition = operator6b.getTokenIndex();
CommonToken token = (CommonToken) input.get(tokenPosition + 1);
UnexpectedSymbolOrConstructionException ex = new UnexpectedSymbolOrConstructionException();
ex.line = token.getLine();
ex.charPositionInLine = token.getStartIndex();
throw ex;
}
| BOOLEAN_FIELD operator7a=(EQ|NE) ~(BOOLEAN_FIELD|BOOLEAN_CONSTANT)
{
int tokenPosition = operator7a.getTokenIndex();
CommonToken token = (CommonToken) input.get(tokenPosition + 1);
IncompatibleTypeException ex = new IncompatibleTypeException();
ex.line = token.getLine();
ex.charPositionInLine = token.getStartIndex();
throw ex;
}
| BOOLEAN_FIELD operator7b=(PLUS|MINUS|LT|LE|GT|GE) (DATE_FIELD|DATE|DATE_CONSTANT|DATE_PERIOD_FIELD|datePeriod|STRING_FIELD|STRING|INTEGER_FIELD|WAIVER_FIELD|BOOLEAN_FIELD|BOOLEAN_CONSTANT)
{
int tokenPosition = operator6b.getTokenIndex();
CommonToken token = (CommonToken) input.get(tokenPosition + 1);
UnexpectedSymbolOrConstructionException ex = new UnexpectedSymbolOrConstructionException();
ex.line = token.getLine();
ex.charPositionInLine = token.getStartIndex();
throw ex;
}
;
// this rule checks that a value is valid. It's not in the validation
// chain
atom
: datePeriod
| DATE_FIELD
| INTEGER_FIELD
| STRING_FIELD
| DATE_PERIOD_FIELD
| WAIVER_FIELD
| BOOLEAN_FIELD
| INTEGER
{
System.out.println("Matched atom INTEGER");
}
| DATE
| DATE_CONSTANT
| BOOLEAN_CONSTANT
| STRING
//| LPAREN expression RPAREN
;
datePeriod
: (DATE_PERIOD_CONSTANT)+
;
// "subatomic" rules, meant to feed the atom rule understandable values
fragment DIGIT: ('0'..'9');
DATE_FIELD:('DOB'|'TEST_DATE');
DATE_PERIOD_FIELD:('AFS');
BOOLEAN_FIELD:('CERTIFIED'|'OVERRIDE');
INTEGER_FIELD:('AGE'|'HT'|'WT');
STRING_FIELD:('CURR_LOC'|'LANG_1'|'LANG_2''USER_LEVEL');
WAIVER_FIELD:('WAIVER');
DATE: /* empty */ {System.out.println("Matched DATE");};
INTEGER: DIGIT+
//INTEGER:('0'..'9')+
{
System.out.println("Matched INTEGER: " + $text);
//$type = INTEGER;
// dynamically change the type when we match the date regular expression
if ($text.matches("(19|20|21)[0-9]{2}[0-1]\\d{3}")) {
//if ($text.matches("(19|20|21)[0-9]{2}[0-1]\\d{3}")) {
System.out.println("Matched date pattern");
$type = DATE;
}
}
;
DATE_PERIOD_CONSTANT: ((INTEGER ' ' YEAR)|(INTEGER ' ' MONTH)|(INTEGER ' ' WEEK)|(INTEGER ' ' DAY))
{
System.out.println("Matched DATE_PERIOD_CONSTANT");
};
DATE_CONSTANT:('TODAY'|'YESTERDAY'|'TOMMOROW');
BOOLEAN_CONSTANT:('TRUE'|'FALSE'|'"Y"'|'"N"');
IF: 'IF';
THEN: 'THEN';
ELSE: 'ELSE';
ENDIF: 'ENDIF';
AND: 'AND';
OR: 'OR';
YEAR: ('YEAR'|'YEARS');
MONTH: ('MONTH'|'MONTHS');
WEEK: ('WEEK'|'WEEKS');
DAY: ('DAY'|'DAYS');
STRING: '"' ID (' ' ID)* '"' {System.out.println("Matched STRING");};
// {
// // strip the quotes once we match this token
// setText(getText().substring(1, getText().length()-1));
// }
// ;
EQ: '=' {System.out.println("Matched EQ");};
NE: '<>';
LT: '<';
LE: '<=';
GT: '>';
GE: '>=';
HAS: 'HAS';
LPAREN: '(';
RPAREN: ')';
PLUS: '+';
MINUS: '-';
SHOW: 'SHOW';
FOR: 'FOR';
ID: ('A'..'Z'|'a'..'z'|'0'..'9'|','|'!'|'?'|':')+ {System.out.println("Matched ID: " + $text);};
COMMENT: ';' ~('\r'|'\n')* {skip();};
WS: (' '+|'\r'|'\n'|'\t') {$channel = HIDDEN;};
最佳答案
每当您的词法分析器“看到”一个数字后跟一个空格时,它就会尝试构造一个 DATE_PERIOD_CONSTANT
。改为将其作为解析器规则:
date_persiod_constant
: INTEGER (YEAR | MONTH | WEEK | DAY)
;
(当然还有删除 DATE_PERIOD_CONSTANT
)
此外,您的 DATE
规则与任何内容都不匹配。我知道您需要此规则来更改 INTEGER
规则的类型,但永远不要创建(可能)不匹配任何内容的词法分析器规则。将 DATE
改为 fragment
:
fragment DATE : ;
即使它是一个片段
,您仍然可以在您的解析器规则中使用DATE
。通过将其设为片段
,您只是在指示词法分析器永远不要自行创建DATE
标记,但是您知道词法分析器可以产生这样的标记,因为当它看起来像一个日期时,您正在更改 INTEGER
的类型。
Is there any way to keep it as a lexer rule? I would really like the date constant to emit a token that I can use later.
当然,这是可能的。不漂亮,但可能:
INTEGER
: DIGIT+ ( (' '+ (YEAR | MONTH | WEEK | DAY))=>
' '+ (YEAR | MONTH | WEEK | DAY) {$type = DATE_PERIOD_CONSTANT;}
)?
{
if ($text.matches("(19|20|21)[0-9]{2}[0-1]\\d{3}")) {
$type = DATE;
}
}
;
fragment DATE_PERIOD_CONSTANT : ;
这样做是在匹配一个或多个数字 DIGIT+
之后,它强制词法分析器在字符流中向前看,看看是否有一个或多个空格后跟 YEAR
、MONTH
、WEEK
或 DAY
,谓词 (' '+ (YEAR | MONTH | WEEK | DAY) )=>
,如果是,它会继续并匹配它(并且您将类型从 INTEGER
更改为 DATE_PERIOD_CONSTANT
)。
One final issue: a DATE period can be something like "1 YEAR 4 MONTHS 2 DAYS", not just a single such as "1 YEAR". Attempting to add a + to the rule was not successful. Can I ask for one more assist in order to make that rule work the way I need it to?
应该这样做(但同样,解析器规则可能更合适!):
INTEGER
: (DATE_PERIOD_CONSTANT)=> DATE_PERIOD_CONSTANT ((' '+ DATE_PERIOD_CONSTANT)=> ' '+ DATE_PERIOD_CONSTANT)*
{
$type=DATE_PERIOD_CONSTANT;
}
| DIGIT+
{
if ($text.matches("(19|20|21)[0-9]{2}[0-1]\\d{3}")) {
System.out.println("Matched date pattern");
$type = DATE;
}
}
;
fragment DATE_PERIOD_CONSTANT
: DIGIT+ ' '+ (YEAR | MONTH | WEEK | DAY)
;
关于java - ANTLR3语法吃整数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13956937/
我正在编写一个具有以下签名的 Java 方法。 void Logger(Method method, Object[] args); 如果一个方法(例如 ABC() )调用此方法 Logger,它应该
我是 Java 新手。 我的问题是我的 Java 程序找不到我试图用作的图像文件一个 JButton。 (目前这段代码什么也没做,因为我只是得到了想要的外观第一的)。这是我的主课 代码: packag
好的,今天我在接受采访,我已经编写 Java 代码多年了。采访中说“Java 垃圾收集是一个棘手的问题,我有几个 friend 一直在努力弄清楚。你在这方面做得怎么样?”。她是想骗我吗?还是我的一生都
我的 friend 给了我一个谜语让我解开。它是这样的: There are 100 people. Each one of them, in his turn, does the following
如果我将使用 Java 5 代码的应用程序编译成字节码,生成的 .class 文件是否能够在 Java 1.4 下运行? 如果后者可以工作并且我正在尝试在我的 Java 1.4 应用程序中使用 Jav
有关于why Java doesn't support unsigned types的问题以及一些关于处理无符号类型的问题。我做了一些搜索,似乎 Scala 也不支持无符号数据类型。限制是Java和S
我只是想知道在一个 java 版本中生成的字节码是否可以在其他 java 版本上运行 最佳答案 通常,字节码无需修改即可在 较新 版本的 Java 上运行。它不会在旧版本上运行,除非您使用特殊参数 (
我有一个关于在命令提示符下执行 java 程序的基本问题。 在某些机器上我们需要指定 -cp 。 (类路径)同时执行java程序 (test为java文件名与.class文件存在于同一目录下) jav
我已经阅读 StackOverflow 有一段时间了,现在我才鼓起勇气提出问题。我今年 20 岁,目前在我的家乡(罗马尼亚克卢日-纳波卡)就读 IT 大学。足以介绍:D。 基本上,我有一家提供簿记应用
我有 public JSONObject parseXML(String xml) { JSONObject jsonObject = XML.toJSONObject(xml); r
我已经在 Java 中实现了带有动态类型的简单解释语言。不幸的是我遇到了以下问题。测试时如下代码: def main() { def ks = Map[[1, 2]].keySet()
一直提示输入 1 到 10 的数字 - 结果应将 st、rd、th 和 nd 添加到数字中。编写一个程序,提示用户输入 1 到 10 之间的任意整数,然后以序数形式显示该整数并附加后缀。 public
我有这个 DownloadFile.java 并按预期下载该文件: import java.io.*; import java.net.URL; public class DownloadFile {
我想在 GUI 上添加延迟。我放置了 2 个 for 循环,然后重新绘制了一个标签,但这 2 个 for 循环一个接一个地执行,并且标签被重新绘制到最后一个。 我能做什么? for(int i=0;
我正在对对象 Student 的列表项进行一些测试,但是我更喜欢在 java 类对象中创建硬编码列表,然后从那里提取数据,而不是连接到数据库并在结果集中选择记录。然而,自从我这样做以来已经很长时间了,
我知道对象创建分为三个部分: 声明 实例化 初始化 classA{} classB extends classA{} classA obj = new classB(1,1); 实例化 它必须使用
我有兴趣使用 GPRS 构建车辆跟踪系统。但是,我有一些问题要问以前做过此操作的人: GPRS 是最好的技术吗?人们意识到任何问题吗? 我计划使用 Java/Java EE - 有更好的技术吗? 如果
我可以通过递归方法反转数组,例如:数组={1,2,3,4,5} 数组结果={5,4,3,2,1}但我的结果是相同的数组,我不知道为什么,请帮助我。 public class Recursion { p
有这样的标准方式吗? 包括 Java源代码-测试代码- Ant 或 Maven联合单元持续集成(可能是巡航控制)ClearCase 版本控制工具部署到应用服务器 最后我希望有一个自动构建和集成环境。
我什至不知道这是否可能,我非常怀疑它是否可能,但如果可以,您能告诉我怎么做吗?我只是想知道如何从打印机打印一些文本。 有什么想法吗? 最佳答案 这里有更简单的事情。 import javax.swin
我是一名优秀的程序员,十分优秀!