Anyone done script system that is written to a file?

Discuss any general programming issues here
jalih
Posts: 276
Joined: Fri Jun 18, 2010 8:08 pm
Location: Finland

Re: Anyone done script system that is written to a file?

Post by jalih »

Bugala wrote: Thu Sep 26, 2019 9:40 am @jalih, yes I would like to take a look at that. Maybe I can use parts of it for my own parser.
Below is a small example on how to use scanner and parser helper module. Notice that when you define keywords and keysyms, "" and #idsym must be at the last index.

Code: Select all

@INCLUDE "./parser/parser.hws"

Const #printstr = 100
Const #addsym   = 101
Const #endsym   = 102

Script = Parser:new()

Function Script:printstr_stmt()
  self:getsym()
  self:expect(#lparen)
  If Not self:accept(#rparen)
    If self:accept(#litstrsym)
      DebugPrint(self:litstr())
    EndIf
    self:expect(#rparen)
  EndIf
EndFunction


Function Script:add_stmt()
  self:getsym()
  self:expect(#lparen)
  self:expect(#numbersym)
  Local a = self:val()
  self:expect(#comma)
  self:expect(#numbersym)
  Local b = self:val()
  self:expect(#rparen)
  DebugPrint(a+b)
EndFunction


Function Script:stmt()
  Switch(self:sym())
    Case #idsym:
      Error("line: " ..self.scanner.cur_line .." column: " ..self.scanner.cur_col ..", unknown command.")
    Case #printstr:
      self:printstr_stmt()
    Case #addsym:
      self:add_stmt()	
  EndSwitch

EndFunction


Function Script:cmpndstmt()
  Repeat
    self:stmt()
    If self:accept(#endsym) Then Break
    If self:accept(#eofsym) Then Error("line: " ..self.scanner.cur_line .." column: " ..self.scanner.cur_col ..", missing end statement.")
  Forever
EndFunction


Function Script:run(fn)
  Local keywords = {}
  keywords[0] = "printstr"
  keywords[1] = "add"
  keywords[2] = "end"
  keywords[3] = ""

  Local keysyms = {}
  keysyms[0] = #printstr
  keysyms[1] = #addsym
  keysyms[2] = #endsym
  keysyms[3] = #idsym

  self:begin_parse(fn, keywords, keysyms)
  self:cmpndstmt()
  self:end_parse()
EndFunction


Script:run("test.txt")
Full project files can be downloaded below, have fun!:

Get scanner and simple parser example
jalih
Posts: 276
Joined: Fri Jun 18, 2010 8:08 pm
Location: Finland

Re: Anyone done script system that is written to a file?

Post by jalih »

Modified my example and updated sample project...

Code: Select all

@INCLUDE "./parser/parser.hws"

Const #printstr = 100
Const #addsym   = 101
Const #endsym   = 102

Script = Parser:new()

Function Script:printstr_stmt()
  self:getsym()
  self:expect(#lparen)
  self:expect(#litstrsym)
  DebugPrint(self:litstr())
  self:expect(#rparen)
EndFunction


Function Script:add_stmt()
  self:getsym()
  self:expect(#lparen)
  self:expect(#numbersym)
  Local a = self:val()
  self:expect(#comma)
  self:expect(#numbersym)
  Local b = self:val()
  self:expect(#rparen)
  DebugPrint(a+b)
EndFunction


Function Script:stmt()
  Switch(self:sym())
    Case #idsym:
      Error("line: " ..self.scanner.cur_line .." column: " ..self.scanner.cur_col ..", unknown command.")
    Case #printstr:
      self:printstr_stmt()
    Case #addsym:
      self:add_stmt()	
  EndSwitch

EndFunction


Function Script:cmpndstmt()
  Repeat
    self:stmt()
    If self:accept(#endsym) Then Break
    If self:accept(#eofsym) Then Error("line: " ..self.scanner.cur_line .." column: " ..self.scanner.cur_col ..", missing end statement.")
  Forever
EndFunction


Function Script:run(fn)
  Local keywords = {}
  keywords[0] = "printstr"
  keywords[1] = "add"
  keywords[2] = "end"
  keywords[3] = ""

  Local keysyms = {}
  keysyms[0] = #printstr
  keysyms[1] = #addsym
  keysyms[2] = #endsym
  keysyms[3] = #idsym

  self:begin_parse(fn, keywords, keysyms)
  self:cmpndstmt()
  self:end_parse()
EndFunction


Script:run("test.txt")
jalih
Posts: 276
Joined: Fri Jun 18, 2010 8:08 pm
Location: Finland

Re: Anyone done script system that is written to a file?

Post by jalih »

A little update... I did some code cleanup... Bugala, did you look at the code? It should easily do everything you need!

Updated parser project

Code: Select all

@INCLUDE "./parser/parser.hws"


; Define some keysym constants
Const #printstr = 100
Const #addsym   = 101
Const #endsym   = 102

; New Parser object that we will be extending
Script = Parser:new()


Function Script:printstr_stmt()
  self:getsym()
  self:expect(#lparen)
  self:expect(#litstrsym)
  DebugPrint(self:litstr())
  self:expect(#rparen)
EndFunction


Function Script:add_stmt()
  self:getsym()
  self:expect(#lparen)
  self:expect(#numbersym)
  Local a = self:val()
  self:expect(#comma)
  self:expect(#numbersym)
  Local b = self:val()
  self:expect(#rparen)
  DebugPrint(a+b)
EndFunction


Function Script:stmt()
  Switch(self:sym())
    Case #idsym:
      Error("line: " ..self:line() .." column: " ..self:col() ..", unknown command.")
    Case #printstr:
      self:printstr_stmt()
    Case #addsym:
      self:add_stmt()	
  EndSwitch

EndFunction


Function Script:cmpndstmt()
  Repeat
    self:stmt()
    If self:accept(#endsym) Then Break
    If self:accept(#eofsym) Then Error("line: " ..self:line() .." column: " ..self:col() ..", missing end statement.")
  Forever
EndFunction


Function Script:run(fn)
  ; Define some keywords
  Local keywords = {}
  keywords[0] = "printstr"
  keywords[1] = "add"
  keywords[2] = "end"
  keywords[3] = ""  ; This must be the last item

  ; Define some keywords
  Local keysyms = {}
  keysyms[0] = #printstr
  keysyms[1] = #addsym
  keysyms[2] = #endsym
  keysyms[3] = #idsym  ; This must be the last item

  self:begin(fn, keywords, keysyms)  ; Start parsing
  self:cmpndstmt()
  self:end()  ; End parsing
EndFunction


Script:run("test.txt")
Bugala
Posts: 1178
Joined: Sun Feb 14, 2010 7:11 pm

Re: Anyone done script system that is written to a file?

Post by Bugala »

Almost forgot to comment back. Yes I took a look at your code and it was useful look. I decided to take for my current script system a different approach, mainly because in your script system there was need to having defined each command as keywords for it to recognise them, and this was problematic for the GOTO idea I was having, since I want to be able to define places in way of "MAIN:" where I can jumpto, and that would mean that I would need to define each place in those keywords before I can use them, which isnt suitable.

Anyway, I am basically going to be making two different parsers for two different kind of scripts, and I dont think the approach I am taking for the first one will solve the problems I am having with the second one, and when I get to there, at least currently I am very much thinking of using your parser as the basis for the second one.

For the second one probably needs to use something like IF-ELSE, or SWITCH, or even calculations. I very much liked that in your parser you were even able to make calculations with it, and + etc. were separately recognised.
jalih
Posts: 276
Joined: Fri Jun 18, 2010 8:08 pm
Location: Finland

Re: Anyone done script system that is written to a file?

Post by jalih »

Bugala wrote: Sat Sep 28, 2019 9:01 am Yes I took a look at your code and it was useful look. I decided to take for my current script system a different approach, mainly because in your script system there was need to having defined each command as keywords for it to recognise them, and this was problematic for the GOTO idea I was having, since I want to be able to define places in way of "MAIN:" where I can jumpto, and that would mean that I would need to define each place in those keywords before I can use them, which isnt suitable.
Keywords need to be defined, but naturally parser and it's scanner can handle labels and variable definitions too. That is what #idsym keysym is really for and scanner returns it, if it encounters unknown undefined keyword. You can use Parser objects id() method to get that scanned word.

If you want to support variables and labels with your script then more work is needed, you need to implement symbol table.
Post Reply