[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Developing a preprocessor for Arduino

From: Pascal J. Bourguignon
Subject: Re: Developing a preprocessor for Arduino
Date: Thu, 02 Jun 2016 15:21:12 -0000
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.5 (gnu/linux)

address@hidden (Csányi Pál) writes:

> Hi,
> I wish to develope a preprocessor for the Arduino programming language.
> I wish to write this preprocessor in Emacs Lisp.
> I imagine that that my pupils write the code in Emacs in their native
> language.
> So, eg. the Arduino command
> setup() will be
> beállít()
> .
> When they finished the program code, they run preprocessor.
> The preprocessor should convert these commands in to English Arduino commands.
> How should I start this project?

Yuri is mostly right.

However, one way to do it would be to write down the grammar of the
language, and extract all the tokens you want to translate in their own
non-terminal rule.

Then you can substitute translations of the tokens in those isolated

You can then translate in both directions, with:

   p1 = (generate g1 (parse g2 p2))
   p2 = (generate g2 (parse g1 p1))

The point here is that the syntactic trees returned by the (parse g2)
and (parse g1) functions are identical down to the terminals isolated in
those simple translated rules), so they can easily be processed by the
generate function of the other grammar, and you get bidirectional
translation for free.

This neutralize one objection thought by Yuri: your students now will be
able to read and maintain foreign code.

Also, if you take care to distinguish non-terminals for homonyms, you
can translate to the correct word.

For example for the language containing those two sentences:

             Move to London.
             Move the apple on the table.

    g1: start     ::= sentence1 | sentence2 .
        sentence1 ::= ntMove1 ntTo ntLondon .
        sentence2 ::= ntMove2 ntThe1 ntApple ntOn ntThe2 ntTable .
        ntMove1   ::= 'Move'   .
        ntTo      ::= 'to'     .
        ntLondon  ::= 'London' .
        ntMove2   ::= 'Move'   .
        ntThe     ::= 'the'    .
        ntApple   ::= 'apple'  .
        ntOn      ::= 'on'     .
        ntThe     ::= 'the'    .
        ntTable   ::= 'table'  .

    g2: start     ::= sentence1 | sentence2 .
        sentence1 ::= ntMove1 ntTo ntLondon .
        sentence2 ::= ntMove2 ntThe ntApple ntOn ntThe ntTable .
        ntMove1   ::= 'Déménager' .
        ntTo      ::= 'à'         .
        ntLondon  ::= 'Londre'    .
        ntMove2   ::= 'Déplacer'  .
        ntThe1    ::= 'la'        .
        ntApple   ::= 'pomme'     .
        ntOn      ::= 'sur'       .
        ntThe2    ::= 'la'        .
        ntTable   ::= 'table'     .

you can see that ntMove1 and ntMove2 don't translate to the same French

For a programming language that should be enough.  However, if the
language is verbose you may want to have also rule transformations.  In
the example above we were lucky that a word-for-word translation
worked.  But with natural languages, there may be different (small) word
numbers, and changes in the order of the matching words, when

You could have rules such as:

    g1:  rule1 ::= ntA ntB ntX.1 ntC ntX.2 ntD ntY ntE .
    g2:  rule1 ::= ntA ntCD ntY ntB1 ntX ntB2.

where the non-terminals ntB ntC ntD and ntE disappear, ntC and ntD being
translated by a single word ntCD, and ntB being translated by two words
ntB1 and ntB2, and the order of ntX and ntY changes.

In those cases, you would have to edit the rule in the new grammar, and
you could transform the syntactic tree by implementing the substitutions
and permutations infered from the two grammar rules.

    g1:  rule1 ::= ntA ntB ntX ntC ntD ntY ntE .
    g2:  rule1 ::= ntA ntY ntB1 ntX.1 ntCD ntX.2 ntB2.

For this to work, you will have to normalize the grammar so that each
alternative is in its own rule, so you dont' have ambiguity when
matching rules in the other language.

You will have to add a (transform g1 g2) function implementing the parse
tree transformations:

   p1 = (generate g1 (transform g1 g2 (parse g2 p2)))
   p2 = (generate g2 (transform g2 g1 (parse g1 p1)))

So you can see that you can easily translate (again, bidirectionnaly) by
writing only three simple functions; generate, transform and parse.

__Pascal Bourguignon__       
“The factory of the future will have only two employees, a man and a
dog. The man will be there to feed the dog. The dog will be there to
keep the man from touching the equipment.” -- Carl Bass CEO Autodesk

reply via email to

[Prev in Thread] Current Thread [Next in Thread]