Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions .github/workflows/build-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,38 @@ jobs:
-WORK ./ .github/workflows/tests/fulldict-hang/input/dash.txt
echo "[#669 regression] analyzer completed without hanging"

- name: Function names with digits regression (#698, Non-20.04)
if: matrix.id != 'docker-ubuntu-20.04'
shell: bash
run: |
set -eo pipefail
# The rule-file tokenizer splits "Round2" into "Round" + "2", so
# user functions whose name held a digit or an underscore never
# matched the "_LIT \(" function grammar and the analyzer died with
# a misleading "[Warning: Missing ';']". The fixture also asserts
# that @RULES literals ("covid19", "a1 \(") still tokenize the old
# way -- the glom must only fire on an unescaped "(".
FIX=.github/workflows/tests/fnname-digits
rm -rf "$FIX/logs" "$FIX/input/text.txt_log"
./bin/nlp -ANA "$FIX" -WORK ./ "$FIX/input/text.txt"
# Windows always leaves a make_ana.log behind; Linux only writes one
# when the build had something to say. Print it if it's there.
if [ -f "$FIX/logs/make_ana.log" ]; then cat "$FIX/logs/make_ana.log"; fi
OUT="$FIX/input/text.txt_log/out.txt"
TREE="$FIX/input/text.txt_log/final.tree"
# nlp exits 0 even when the analyzer fails to build, so assert the
# output, not the exit code.
if [ ! -f "$OUT" ]; then
echo "FAIL(#698): no out.txt -- the analyzer did not build"; exit 1
fi
got=$(tr -d '\r' < "$OUT")
if [ "$got" != "3 21 201 2001 1 8 71" ]; then
echo "FAIL(#698): out.txt was '$got'"; exit 1
fi
grep -q '_COVID' "$TREE" || { echo "FAIL(#698): literal covid19 no longer matches two tokens"; exit 1; }
grep -q '_APAREN' "$TREE" || { echo "FAIL(#698): escaped '\\(' literal regressed"; exit 1; }
echo "[#698 regression] digit/underscore function names compile and run"

- name: Copy nlp.exe to nlpl.exe (Non-20.04)
if: matrix.id != 'docker-ubuntu-20.04'
run: cp bin/nlp bin/nlpl.exe
Expand Down
31 changes: 31 additions & 0 deletions .github/workflows/build-windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,37 @@ jobs:
-WORK ./ .github/workflows/tests/fulldict-hang/input/dash.txt
echo "[#669 regression] analyzer completed without hanging"

- name: Function names with digits regression (#698)
shell: bash
run: |
set -eo pipefail
# The rule-file tokenizer splits "Round2" into "Round" + "2", so
# user functions whose name held a digit or an underscore never
# matched the "_LIT \(" function grammar and the analyzer died with
# a misleading "[Warning: Missing ';']". The fixture also asserts
# that @RULES literals ("covid19", "a1 \(") still tokenize the old
# way -- the glom must only fire on an unescaped "(".
FIX=.github/workflows/tests/fnname-digits
rm -rf "$FIX/logs" "$FIX/input/text.txt_log"
./bin/Release/nlp.exe -ANA "$FIX" -WORK ./ "$FIX/input/text.txt"
# Windows always leaves a make_ana.log behind; Linux only writes one
# when the build had something to say. Print it if it's there.
if [ -f "$FIX/logs/make_ana.log" ]; then cat "$FIX/logs/make_ana.log"; fi
OUT="$FIX/input/text.txt_log/out.txt"
TREE="$FIX/input/text.txt_log/final.tree"
# nlp exits 0 even when the analyzer fails to build, so assert the
# output, not the exit code.
if [ ! -f "$OUT" ]; then
echo "FAIL(#698): no out.txt -- the analyzer did not build"; exit 1
fi
got=$(tr -d '\r' < "$OUT")
if [ "$got" != "3 21 201 2001 1 8 71" ]; then
echo "FAIL(#698): out.txt was '$got'"; exit 1
fi
grep -q '_COVID' "$TREE" || { echo "FAIL(#698): literal covid19 no longer matches two tokens"; exit 1; }
grep -q '_APAREN' "$TREE" || { echo "FAIL(#698): escaped '\\(' literal regressed"; exit 1; }
echo "[#698 regression] digit/underscore function names compile and run"

- name: Copy nlp.exe to nlpw.exe
run: cp bin/Release/nlp.exe bin/Release/nlpw.exe
shell: bash
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/tests/fnname-digits/input/text.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
covid19 a1( x
1 change: 1 addition & 0 deletions .github/workflows/tests/fnname-digits/kb/user/.gitkeep
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Placeholder so git tracks kb/user; the engine needs the dir to exist.
3 changes: 3 additions & 0 deletions .github/workflows/tests/fnname-digits/spec/analyzer.seq
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
tokenize nil # tokenize only -- fixture needs no dictionary
nlp fndigits # #698: function names containing digits/underscores
nlp lits # @RULES literals must tokenize as before
59 changes: 59 additions & 0 deletions .github/workflows/tests/fnname-digits/spec/fndigits.nlp
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
###############################################
# FILE: fndigits.nlp
# SUBJ: Regression for issue #698 -- user function names that contain a
# digit or an underscore.
# NOTE: The rule-file tokenizer splits "Round2" into "Round" + "2", so
# before the fix every one of these definitions died with a
# misleading "[Warning: Missing ';']" + "[Syntax error.]" and the
# analyzer never built. Expected out.txt: "3 21 201 2001 1 8 71".
###############################################

@DECL

Round2(L("x")) {
return L("x") + 2;
}

R2ound(L("x")) {
return L("x") + 20;
}

x2Round(L("x")) {
return L("x") + 200;
}

Round_2(L("x")) {
return L("x") + 2000;
}

Clamp01(L("x")) {
if (L("x") > 1)
return 1;
if (L("x") < 0)
return 0;
return L("x");
}

# Digits in LOCAL VARIABLE names always worked. Keep checking them.
RoundTwo(L("x2")) {
L("y2") = L("x2") + 7;
return L("y2");
}

Round_Two(L("x")) {
return L("x") + 70;
}

@@DECL

@CODE

"out.txt" << str(Round2(1)) << " ";
"out.txt" << str(R2ound(1)) << " ";
"out.txt" << str(x2Round(1)) << " ";
"out.txt" << str(Round_2(1)) << " ";
"out.txt" << str(Clamp01(5)) << " ";
"out.txt" << str(RoundTwo(1)) << " ";
"out.txt" << str(Round_Two(1)) << "\n";

@@CODE
16 changes: 16 additions & 0 deletions .github/workflows/tests/fnname-digits/spec/lits.nlp
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
###############################################
# FILE: lits.nlp
# SUBJ: Guard the OTHER half of issue #698's fix: glomming digit-bearing
# names must NOT change how @RULES literals tokenize.
# NOTE: "covid19" must stay TWO rule elements ("covid" then "19") so it
# keeps matching the two tokens the text tokenizer produces, and an
# escaped "\(" must not trigger the function-name glom.
###############################################

@NODES _ROOT

@RULES
_COVID <- covid19 @@

@RULES
_APAREN <- a1 \( @@
22 changes: 22 additions & 0 deletions data/rfb/spec/bigtok.nlp
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,28 @@ _NONLIT [base] <- \_ _xWILD [s plus match=(_xALPHA _xEMOJI _xNUM)] @@ # 06/11/26
@RULES
_ARROW [base] <- \< \- @@

# FUNCTION NAMES CONTAINING DIGITS OR UNDERSCORES. # 07/26/26 DD.
# The rule-file tokenizer splits "Round2" into "Round" + "2", so a user
# function named Round2 (or Clamp01, Round_2, Fixed2) never matched the
# _LIT \( function grammar and died with a misleading "Missing ';'".
# Glom the adjacent alpha/numeric/underscore tokens back into one _LIT,
# but ONLY when they are immediately followed by an UNESCAPED "(" -- ie, a
# function definition header or a function call. @RULES literals write
# "\(" and key=(val) pairs put "=" before the paren, so element literals
# and pair values keep their old tokenization.
# The second element is [plus], so single-token names (if, while, return,
# L, N, X, G, P, s) never come here; they fall through to the keyword
# rules below.
@POST
rfaname(1,2)
singler(1,2)
@RULES
_LIT [base] <-
_xALPHA
_xWILD [s plus match=(_xALPHA _xNUM \_)]
\( [lookahead]
@@

@POST
rfaname(1)
single()
Expand Down
18 changes: 18 additions & 0 deletions include/Api/lite/Arun.h
Original file line number Diff line number Diff line change
Expand Up @@ -1789,6 +1789,24 @@ class LITE_API Arun
static float logten(Nlppp*,RFASem*); // 04/29/04 AM.
static float logten(Nlppp*,float); // 04/29/04 AM.

// Math functions. // 07/26/26 DD.
static long long floor(Nlppp*,RFASem*);
static long long floor(Nlppp*,float);
static long long ceiling(Nlppp*,RFASem*);
static long long ceiling(Nlppp*,float);
static long long round(Nlppp*,RFASem*);
static long long round(Nlppp*,float);
static long long truncate(Nlppp*,RFASem*);
static long long truncate(Nlppp*,float);
static float sqrt(Nlppp*,RFASem*);
static float sqrt(Nlppp*,float);
static float log(Nlppp*,RFASem*);
static float log(Nlppp*,float);
static float pow(Nlppp*,RFASem*,RFASem*);
static float pow(Nlppp*,RFASem*,float);
static float pow(Nlppp*,float,RFASem*);
static float pow(Nlppp*,float,float);


static _TCHAR *urltofile(Nlppp*,_TCHAR*,_TCHAR*); // 05/14/14 AM.
static _TCHAR *urltofile(Nlppp*,RFASem*,_TCHAR*); // 05/14/14 AM.
Expand Down
Loading
Loading