Skip to content

Commit b311ab8

Browse files
committed
Parse optional timestamp
1 parent 19c9e03 commit b311ab8

File tree

2 files changed

+71
-63
lines changed

2 files changed

+71
-63
lines changed

docs/index.js

Lines changed: 30 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -16,28 +16,17 @@ import * as Data_String_Regex_Flags from "https://compile.purescript.org/output/
1616
import * as Data_String_Regex_Unsafe from "https://compile.purescript.org/output/Data.String.Regex.Unsafe/index.js";
1717
import * as Effect_Console from "https://compile.purescript.org/output/Effect.Console/index.js";
1818
import * as StringParser_CodePoints from "https://compile.purescript.org/output/StringParser.CodePoints/index.js";
19+
import * as StringParser_Combinators from "https://compile.purescript.org/output/StringParser.Combinators/index.js";
1920
import * as StringParser_Parser from "https://compile.purescript.org/output/StringParser.Parser/index.js";
2021
var discard = /* #__PURE__ */ Control_Bind.discard(Control_Bind.discardUnit);
2122
var discard1 = /* #__PURE__ */ discard(StringParser_Parser.bindParser);
23+
var applyFirst = /* #__PURE__ */ Control_Apply.applyFirst(StringParser_Parser.applyParser);
2224

23-
// To parse the line: `stack_dump: 0xc02027e0: c0202010 00000000 00000001 00000000 00000000 00000000 8000ad8a 00000000`
24-
// If the line begins with a Timestamp: `[ 6.242000] `
25-
// Skip `[ `
26-
// `void` means ignore the Text Captured
27-
// `$ something something` is shortcut for `( something something )`
28-
// `<*` is the Delimiter between Patterns
29-
// void $
30-
// string "[" -- Match the string `[`
31-
// <* skipSpaces -- Skip the following spaces
32-
// <* regex "[.0-9]+" -- Skip the number
33-
// <* string "]" -- Match the string `]`
34-
// <* skipSpaces -- Skip the following spaces
3525
// Skip `stack_dump: `
3626
// `void` means ignore the Text Captured
3727
// `$ something something` is shortcut for `( something something )`
3828
// `<*` is the Delimiter between Patterns
3929
var $$void = /* #__PURE__ */ Data_Functor["void"](StringParser_Parser.functorParser);
40-
var applyFirst = /* #__PURE__ */ Control_Apply.applyFirst(StringParser_Parser.applyParser);
4130
var bind = /* #__PURE__ */ Control_Bind.bind(StringParser_Parser.bindParser);
4231
var pure = /* #__PURE__ */ Control_Applicative.pure(StringParser_Parser.applicativeParser);
4332
var show = /* #__PURE__ */ Data_Show.show(Data_Show.showInt);
@@ -103,7 +92,7 @@ var showAddressType = {
10392
if (v instanceof Heap) {
10493
return "Heap";
10594
};
106-
throw new Error("Failed pattern match at Main (line 73, column 1 - line 77, column 21): " + [ v.constructor.name ]);
95+
throw new Error("Failed pattern match at Main (line 79, column 1 - line 83, column 21): " + [ v.constructor.name ]);
10796
}
10897
};
10998

@@ -123,27 +112,29 @@ var logShow1 = /* #__PURE__ */ Effect_Console.logShow(/* #__PURE__ */ Data_Maybe
123112
// Given this line of NuttX Stack Dump: `stack_dump: 0xc02027e0: c0202010 00000000 00000001 00000000 00000000 00000000 8000ad8a 00000000`
124113
// Result: { addr: "c02027e0", timestamp: "6.242000", v1: "c0202010", v2: "00000000", v3: "00000001", v4: "00000000", v5: "00000000", v6: "00000000", v7: "8000ad8a", v8: "00000000" }
125114
// The next line declares the Function Type. We can actually erase it, VSCode PureScript Extension will helpfully suggest it for us.
126-
var parseStackDump = /* #__PURE__ */ discard1(/* #__PURE__ */ $$void(/* #__PURE__ */ applyFirst(/* #__PURE__ */ StringParser_CodePoints.string("stack_dump:"))(StringParser_CodePoints.skipSpaces)))(function () {
127-
return discard1($$void(StringParser_CodePoints.string("0x")))(function () {
128-
return bind(applyFirst(applyFirst(StringParser_CodePoints.regex("[0-9a-f]+"))(StringParser_CodePoints.string(":")))(StringParser_CodePoints.skipSpaces))(function (addr) {
129-
return bind(applyFirst(StringParser_CodePoints.regex("[0-9a-f]+"))(StringParser_CodePoints.skipSpaces))(function (v1) {
130-
return bind(applyFirst(StringParser_CodePoints.regex("[0-9a-f]+"))(StringParser_CodePoints.skipSpaces))(function (v2) {
131-
return bind(applyFirst(StringParser_CodePoints.regex("[0-9a-f]+"))(StringParser_CodePoints.skipSpaces))(function (v3) {
132-
return bind(applyFirst(StringParser_CodePoints.regex("[0-9a-f]+"))(StringParser_CodePoints.skipSpaces))(function (v4) {
133-
return bind(applyFirst(StringParser_CodePoints.regex("[0-9a-f]+"))(StringParser_CodePoints.skipSpaces))(function (v5) {
134-
return bind(applyFirst(StringParser_CodePoints.regex("[0-9a-f]+"))(StringParser_CodePoints.skipSpaces))(function (v6) {
135-
return bind(applyFirst(StringParser_CodePoints.regex("[0-9a-f]+"))(StringParser_CodePoints.skipSpaces))(function (v7) {
136-
return bind(applyFirst(StringParser_CodePoints.regex("[0-9a-f]+"))(StringParser_CodePoints.skipSpaces))(function (v8) {
137-
return pure({
138-
addr: addr,
139-
v1: v1,
140-
v2: v2,
141-
v3: v3,
142-
v4: v4,
143-
v5: v5,
144-
v6: v6,
145-
v7: v7,
146-
v8: v8
115+
var parseStackDump = /* #__PURE__ */ discard1(/* #__PURE__ */ StringParser_Combinators.optional(/* #__PURE__ */ applyFirst(/* #__PURE__ */ applyFirst(/* #__PURE__ */ applyFirst(/* #__PURE__ */ applyFirst(/* #__PURE__ */ StringParser_CodePoints.string("["))(StringParser_CodePoints.skipSpaces))(/* #__PURE__ */ StringParser_CodePoints.regex("[.0-9]+")))(/* #__PURE__ */ StringParser_CodePoints.string("]")))(StringParser_CodePoints.skipSpaces)))(function () {
116+
return discard1($$void(applyFirst(StringParser_CodePoints.string("stack_dump:"))(StringParser_CodePoints.skipSpaces)))(function () {
117+
return discard1($$void(StringParser_CodePoints.string("0x")))(function () {
118+
return bind(applyFirst(applyFirst(StringParser_CodePoints.regex("[0-9a-f]+"))(StringParser_CodePoints.string(":")))(StringParser_CodePoints.skipSpaces))(function (addr) {
119+
return bind(applyFirst(StringParser_CodePoints.regex("[0-9a-f]+"))(StringParser_CodePoints.skipSpaces))(function (v1) {
120+
return bind(applyFirst(StringParser_CodePoints.regex("[0-9a-f]+"))(StringParser_CodePoints.skipSpaces))(function (v2) {
121+
return bind(applyFirst(StringParser_CodePoints.regex("[0-9a-f]+"))(StringParser_CodePoints.skipSpaces))(function (v3) {
122+
return bind(applyFirst(StringParser_CodePoints.regex("[0-9a-f]+"))(StringParser_CodePoints.skipSpaces))(function (v4) {
123+
return bind(applyFirst(StringParser_CodePoints.regex("[0-9a-f]+"))(StringParser_CodePoints.skipSpaces))(function (v5) {
124+
return bind(applyFirst(StringParser_CodePoints.regex("[0-9a-f]+"))(StringParser_CodePoints.skipSpaces))(function (v6) {
125+
return bind(applyFirst(StringParser_CodePoints.regex("[0-9a-f]+"))(StringParser_CodePoints.skipSpaces))(function (v7) {
126+
return bind(applyFirst(StringParser_CodePoints.regex("[0-9a-f]+"))(StringParser_CodePoints.skipSpaces))(function (v8) {
127+
return pure({
128+
addr: addr,
129+
v1: v1,
130+
v2: v2,
131+
v3: v3,
132+
v4: v4,
133+
v5: v5,
134+
v6: v6,
135+
v7: v7,
136+
v8: v8
137+
});
147138
});
148139
});
149140
});
@@ -157,10 +148,6 @@ var parseStackDump = /* #__PURE__ */ discard1(/* #__PURE__ */ $$void(/* #__PURE_
157148
});
158149
});
159150

160-
// Parse the line of NuttX Stack Dump with Timestamp
161-
// Result: { addr: "c02027e0", v1: "c0202010", v2: "00000000", v3: "00000001", v4: "00000000", v5: "00000000", v6: "00000000", v7: "8000ad8a", v8: "00000000" }
162-
// doRunParser "parseStackDump" parseStackDump
163-
// "[ 6.242000] stack_dump: 0xc02027e0: c0202010 00000000 00000001 00000000 00000000 00000000 8000ad8a 00000000"
164151
// Parse the NuttX Exception.
165152
// Given this NuttX Exception: `riscv_exception: EXCEPTION: Instruction page fault. MCAUSE: 000000000000000c, EPC: 000000008000ad8a, MTVAL: 000000008000ad8a`
166153
// Result: { epc: "8000ad8a", exception: "Instruction page fault", mcause: 12, mtval: "8000ad8a" }
@@ -214,7 +201,7 @@ var identifyAddress = function (addr) {
214201
if (Data_Boolean.otherwise) {
215202
return Data_Maybe.Nothing.value;
216203
};
217-
throw new Error("Failed pattern match at Main (line 57, column 1 - line 57, column 74): " + [ addr.constructor.name ]);
204+
throw new Error("Failed pattern match at Main (line 57, column 1 - line 63, column 6): " + [ addr.constructor.name ]);
218205
};
219206

220207
// Given this NuttX Exception: `riscv_exception: EXCEPTION: Load page fault. MCAUSE: 000000000000000d, EPC: 000000008000a0e4, MTVAL: 0000000880203b88`
@@ -252,7 +239,7 @@ var doRunParser = function (dictShow) {
252239
if (v instanceof Data_Either.Right) {
253240
return Effect_Console.log("Result: " + show1(v.value0))();
254241
};
255-
throw new Error("Failed pattern match at Main (line 262, column 3 - line 264, column 52): " + [ v.constructor.name ]);
242+
throw new Error("Failed pattern match at Main (line 282, column 3 - line 284, column 52): " + [ v.constructor.name ]);
256243
})();
257244
return Effect_Console.log("-----")();
258245
};
@@ -327,7 +314,8 @@ var printResults = function __do() {
327314
logShow1(identifyAddress("8000a0e4"))();
328315
logShow1(identifyAddress("0000000800203b88"))();
329316
doRunParser1("parseException")(parseException)("riscv_exception: EXCEPTION: Instruction page fault. MCAUSE: 000000000000000c, EPC: 000000008000ad8a, MTVAL: 000000008000ad8a")();
330-
return doRunParser2("parseStackDump")(parseStackDump)("stack_dump: 0xc02027e0: c0202010 00000000 00000001 00000000 00000000 00000000 8000ad8a 00000000")();
317+
doRunParser2("parseStackDump")(parseStackDump)("stack_dump: 0xc02027e0: c0202010 00000000 00000001 00000000 00000000 00000000 8000ad8a 00000000")();
318+
return doRunParser2("parseStackDump")(parseStackDump)("[ 6.242000] stack_dump: 0xc02027e0: c0202010 00000000 00000001 00000000 00000000 00000000 8000ad8a 00000000")();
331319
};
332320

333321
// Main Function that will run our Test Code.

src/Main.purs

Lines changed: 41 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import Data.String.Regex.Flags (noFlags)
1818
import Data.String.Regex.Unsafe (unsafeRegex)
1919
import Effect (Effect)
2020
import Effect.Console (log, logShow)
21-
import StringParser (Parser, regex, runParser, skipSpaces, string)
21+
import StringParser (Parser, optional, regex, runParser, skipSpaces, string)
2222

2323
-- Main Function that will run our Test Code.
2424
-- `Effect` says that it will do Side Effects (printing to console)
@@ -30,7 +30,7 @@ main = printResults -- Run our Test Code and print the results
3030
-- Given this NuttX Exception: `riscv_exception: EXCEPTION: Load page fault. MCAUSE: 000000000000000d, EPC: 000000008000a0e4, MTVAL: 0000000880203b88`
3131
-- Explain in friendly words: "We hit a Load Page Fault. Our code at Code Address 8000a0e4 tried to access the Data Address 0000000880203b88, which is Invalid."
3232
-- The next line declares the Function Type. We can actually erase it, VSCode PureScript Extension will helpfully suggest it for us.
33-
explainException
33+
explainException
3434
Int -- MCAUSE: Cause of Exception
3535
String -- EPC: Exception Program Counter
3636
String -- MTVAL: Exception Value
@@ -54,7 +54,13 @@ explainException mcause epc mtval =
5454
"Unknown Exception: mcause=" <> show mcause <> ", epc=" <> epc <> ", mtval=" <> mtval
5555

5656
-- Given an Address, identify the Origin (NuttX Kernel or App) and Type (Code / Data / BSS / Heap)
57-
identifyAddress String Maybe { origin String , type AddressType }
57+
identifyAddress
58+
String -- Address: `502198ac`
59+
Maybe -- If Unknown Address: Return `Nothing`
60+
{ -- Else return...
61+
origin String -- Origin: `nuttx` or `qjs`
62+
, type AddressType -- Type: Code / Data / BSS / Heap
63+
}
5864

5965
-- Address 502xxxxx comes from NuttX Kernel Code
6066
-- Address 800xxxxx comes from NuttX App Code (QuickJS)
@@ -78,13 +84,16 @@ instance Show AddressType where
7884

7985
-- Return True if the Address matches the Regex Pattern.
8086
-- Pattern is assumed to match the Entire Address.
81-
matches String String Boolean
87+
matches
88+
String -- Pattern: `502.....`
89+
String -- Address: `502198ac`
90+
Boolean -- Return True if Address matches Regex `^502.....$`
8291

8392
-- Match the Begin `^` and End `$` of the Address
8493
-- `<>` will concat 2 strings
8594
-- "a `unsafeRegex` b" is same as "(unsafeRegex a b)"
86-
matches pattern addr =
87-
let
95+
matches pattern addr =
96+
let
8897
patternWrap = "^" <> pattern <> "$"
8998
in
9099
isJust $ -- Is there a Match...
@@ -122,8 +131,8 @@ printResults = do
122131

123132
-- Parse the line of NuttX Stack Dump with Timestamp
124133
-- Result: { addr: "c02027e0", v1: "c0202010", v2: "00000000", v3: "00000001", v4: "00000000", v5: "00000000", v6: "00000000", v7: "8000ad8a", v8: "00000000" }
125-
-- doRunParser "parseStackDump" parseStackDump
126-
-- "[ 6.242000] stack_dump: 0xc02027e0: c0202010 00000000 00000001 00000000 00000000 00000000 8000ad8a 00000000"
134+
doRunParser "parseStackDump" parseStackDump
135+
"[ 6.242000] stack_dump: 0xc02027e0: c0202010 00000000 00000001 00000000 00000000 00000000 8000ad8a 00000000"
127136

128137
-- Parse the NuttX Exception.
129138
-- Given this NuttX Exception: `riscv_exception: EXCEPTION: Instruction page fault. MCAUSE: 000000000000000c, EPC: 000000008000ad8a, MTVAL: 000000008000ad8a`
@@ -152,9 +161,9 @@ parseException = do
152161

153162
-- `exception` becomes `Instruction page fault`
154163
-- `<*` says when we should stop the Text Capture
155-
exception <- regex "[^.]+"
156-
<* string "."
157-
<* skipSpaces
164+
exception <- regex "[^.]+"
165+
<* string "."
166+
<* skipSpaces
158167

159168
-- Skip `MCAUSE: `
160169
-- `void` means ignore the Text Captured
@@ -181,7 +190,7 @@ parseException = do
181190
-- Return the parsed content
182191
-- `pure` because we're in a `do` block that allows (Side) Effects
183192
-- TODO: Return a ParseError instead of -1
184-
pure
193+
pure
185194
{
186195
exception
187196
, mcause:
@@ -201,22 +210,33 @@ parseException = do
201210
-- Given this line of NuttX Stack Dump: `stack_dump: 0xc02027e0: c0202010 00000000 00000001 00000000 00000000 00000000 8000ad8a 00000000`
202211
-- Result: { addr: "c02027e0", timestamp: "6.242000", v1: "c0202010", v2: "00000000", v3: "00000001", v4: "00000000", v5: "00000000", v6: "00000000", v7: "8000ad8a", v8: "00000000" }
203212
-- The next line declares the Function Type. We can actually erase it, VSCode PureScript Extension will helpfully suggest it for us.
204-
parseStackDump Parser { addr String , v1 String , v2 String , v3 String , v4 String , v5 String , v6 String , v7 String , v8 String }
205-
parseStackDump = do
213+
parseStackDump Parser -- We're creating a Parser...
214+
{ -- That accepts a String and returns...
215+
addr String -- Address: `c02027e0`
216+
, v1 String -- Value 1: `c0202010`
217+
, v2 String -- Value 2: `00000000`
218+
, v3 String -- Value 3: `00000001`
219+
, v4 String -- Value 4: `00000000`
220+
, v5 String -- Value 5: `00000000`
221+
, v6 String -- Value 6: `00000000`
222+
, v7 String -- Value 7: `8000ad8a`
223+
, v8 String -- Value 8: `00000000`
224+
}
206225

207-
-- To parse the line: `stack_dump: 0xc02027e0: c0202010 00000000 00000001 00000000 00000000 00000000 8000ad8a 00000000`
226+
-- To parse the line: `stack_dump: 0xc02027e0: c0202010 00000000 00000001 00000000 00000000 00000000 8000ad8a 00000000`
227+
parseStackDump = do
208228

209229
-- If the line begins with a Timestamp: `[ 6.242000] `
210230
-- Skip `[ `
211231
-- `void` means ignore the Text Captured
212232
-- `$ something something` is shortcut for `( something something )`
213233
-- `<*` is the Delimiter between Patterns
214-
-- void $
215-
-- string "[" -- Match the string `[`
216-
-- <* skipSpaces -- Skip the following spaces
217-
-- <* regex "[.0-9]+" -- Skip the number
218-
-- <* string "]" -- Match the string `]`
219-
-- <* skipSpaces -- Skip the following spaces
234+
optional $ -- Timestamp may or may not appear
235+
string "[" -- Match the string `[`
236+
<* skipSpaces -- Skip the following spaces
237+
<* regex "[.0-9]+" -- Skip the number
238+
<* string "]" -- Match the string `]`
239+
<* skipSpaces -- Skip the following spaces
220240

221241
-- Skip `stack_dump: `
222242
-- `void` means ignore the Text Captured

0 commit comments

Comments
 (0)