diff options
| author | Cliff Click <cliffc@acm.org> | 2026-11-11 15:40:22 -0800 |
|---|---|---|
| committer | Cliff Click <cliffc@acm.org> | 2026-11-12 13:48:30 -0800 |
| commit | 0720fd8ed0aa92248622a9f3c3ebd522b002fd91 (patch) | |
| tree | 3ba939eb4e786373cedc54e1afe0bbdbfd16dc01 /chapter31/src/main/java/com | |
| parent | 18c04fd4aab0ad0bf3b3eece9551cc7aa7b9f796 (diff) | |
| download | Simple-0720fd8ed0aa92248622a9f3c3ebd522b002fd91.tar.gz Simple-0720fd8ed0aa92248622a9f3c3ebd522b002fd91.zip | |
graphic tictactoe
Hex & octal digits
Diffstat (limited to 'chapter31/src/main/java/com')
| -rw-r--r-- | chapter31/src/main/java/com/seaofnodes/simple/parser/Expressions.java | 2 | ||||
| -rw-r--r-- | chapter31/src/main/java/com/seaofnodes/simple/parser/Lexer.java | 26 |
2 files changed, 26 insertions, 2 deletions
diff --git a/chapter31/src/main/java/com/seaofnodes/simple/parser/Expressions.java b/chapter31/src/main/java/com/seaofnodes/simple/parser/Expressions.java index 247d974e..6486aba8 100644 --- a/chapter31/src/main/java/com/seaofnodes/simple/parser/Expressions.java +++ b/chapter31/src/main/java/com/seaofnodes/simple/parser/Expressions.java @@ -400,7 +400,7 @@ final class Expressions { * Parse integer literal * * <pre> - * integerLiteral: [1-9][0-9]* | [0] + * integerLiteral: [1-9][0-9]* | 0[0-7]* | 0[xX][0-9a-fA-F]+ * floatLiteral: [digits].[digits]?[e [digits]]?[f]? * </pre> */ diff --git a/chapter31/src/main/java/com/seaofnodes/simple/parser/Lexer.java b/chapter31/src/main/java/com/seaofnodes/simple/parser/Lexer.java index 5e4b7311..9ab678ca 100644 --- a/chapter31/src/main/java/com/seaofnodes/simple/parser/Lexer.java +++ b/chapter31/src/main/java/com/seaofnodes/simple/parser/Lexer.java @@ -239,6 +239,7 @@ public class Lexer { // Return a constant Type, either TypeInteger or TypeFloat Type parseNumber() { Lexer start=new Lexer(this); + if( isHex() ) return parseInteger(parseNumberString(),16,2,start); int old = _position; int len = isLongOrDouble(); boolean f32 = peek()=='f'; @@ -250,7 +251,7 @@ public class Lexer { return TypeFloat.constant(Float.parseFloat(literal)); if( len > 0 ) { if( len > 1 && _input[old]=='0' ) - throw Parser.error("Syntax error: integer values cannot start with '0'",start); + return parseInteger(literal,8,0,start); long i = Long.parseLong(literal); return TypeInteger.constant(i); } @@ -262,6 +263,11 @@ public class Lexer { } private String parseNumberString() { int old = _position; + if( isHex() ) { + _position += 2; + while( isIdLetter(peek()) ) inc(); + return new String(_input,old,_position-old); + } int len = Math.abs(isLongOrDouble()); if( peek()=='f' ) { nextChar(); @@ -270,6 +276,24 @@ public class Lexer { return new String(_input,old,len); } + private boolean isHex() { + return peek()=='0' && _position+1<_input.length && (peek(1)=='x' || peek(1)=='X'); + } + + private TypeInteger parseInteger(String literal, int radix, int prefix, Lexer start) { + String kind = radix==16 ? "Hexadecimal" : "Octal"; + if( literal.length()==prefix ) + throw Parser.error(kind+" integer literal requires at least one digit",start); + for( int i=prefix; i<literal.length(); i++ ) + if( Character.digit(literal.charAt(i),radix)<0 ) + throw Parser.error("Invalid "+kind.toLowerCase()+" integer literal '"+literal+"'",start); + try { + return TypeInteger.constant(Long.parseUnsignedLong(literal.substring(prefix),radix)); + } catch( NumberFormatException ex ) { + throw Parser.error(kind+" integer literal exceeds 64 bits",start); + } + } + // Return +len that ends a long // Return -len that ends a double private int isLongOrDouble() { |
