From 0720fd8ed0aa92248622a9f3c3ebd522b002fd91 Mon Sep 17 00:00:00 2001 From: Cliff Click Date: Wed, 11 Nov 2026 15:40:22 -0800 Subject: graphic tictactoe Hex & octal digits --- .../com/seaofnodes/simple/parser/Expressions.java | 2 +- .../java/com/seaofnodes/simple/parser/Lexer.java | 26 +++++++++++++++++++++- 2 files changed, 26 insertions(+), 2 deletions(-) (limited to 'chapter31/src/main/java/com') 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 * *
-     *     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]?
      * 
*/ 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